2 * Copyright (C) 1999,2000 the Free Software Foundation.
3 * Copyright (C) 2000 Eazel, Inc.
4 * Copyright (C) 2001-2011 George (Jiri) Lebl
5 * Copyright © 2019-2022 Nick Bowler
7 * Author: George (Jiri) Lebl
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
37 #include "treefuncs.h"
48 static const char sopts[] = SOPT_STRING;
49 static const struct option lopts[] = {
54 char *filename = NULL;
64 extern GList *include_files;
66 extern GHashTable *gtk_doc_hash;
70 static char *outfilebase;
71 static char *outfilehbase;
72 static char *outfilephbase;
73 static char *funcbase;
74 static char *pfuncbase;
75 static char *macrobase;
77 static char *pmacrois;
78 static char *macrotype;
79 static char *pmacrotype;
80 static char *typebase;
81 static char *ptypebase;
83 char *output_dir = NULL;
87 static int signals = 0; /* number of signals */
88 static int set_properties = 0; /* number of named (set) properties */
89 static int get_properties = 0; /* number of named (get) properties */
90 static int overrides = 0; /* number of override methods */
91 static int privates = 0; /* number of private data members */
92 static int protecteds = 0; /* number of protected methods */
93 static int unreftors = 0; /* number of variable unreffing destructors */
94 static int destructors = 0; /* number of variable non-unreffing destructors */
95 static int initializers = 0; /* number of variable initializers */
96 static int glade_widgets = 0; /* number of glade widgets */
97 static gboolean overrode_get_type = FALSE; /* provided your won _get_type */
99 static gboolean made_aliases = FALSE; /* if we made any shorthand aliases
100 and need the REALLY UGLY HACK to
103 /* the special variable types we need to define */
104 static gboolean special_array[SPECIAL_LAST] = {0};
105 static gboolean any_special = FALSE;
107 static gboolean need_constructor = FALSE;
108 static Method * user_constructor = NULL;
110 static gboolean need_dispose = FALSE;
111 static Method * dispose_handler = NULL;
112 static Method * user_dispose_method = NULL;
114 static gboolean need_finalize = FALSE;
115 static Method * finalize_handler = NULL;
116 static Method * user_finalize_method = NULL;
122 gboolean no_touch = FALSE;
123 gboolean no_touch_headers = FALSE;
124 gboolean for_cpp = FALSE;
125 gboolean no_gnu = FALSE;
126 gboolean exit_on_warn = FALSE;
127 gboolean exit_on_error = TRUE;
128 gboolean got_error = FALSE;
129 gint private_header = PRIVATE_HEADER_ONDEMAND;
130 gboolean no_extern_c = FALSE;
131 gboolean no_write = FALSE;
132 gboolean no_lines = FALSE;
133 gboolean no_self_alias = FALSE;
134 gboolean always_private_struct = FALSE;
135 gboolean gtk3_ok = FALSE;
141 gboolean use_m4 = FALSE; /* preprocess sources with m4 */
142 char *m4_commandline = NULL;
143 #define M4_INCLUDE_DIR PKGDATADIR "/m4"
144 #define M4_BASE_FILENAME "gobm4.m4"
145 #define M4_FLAGS "-P -s -I" M4_INCLUDE_DIR " -DGOBM4_GOB_VERSION=" VERSION " " M4_BASE_FILENAME
146 #define M4_COMMANDLINE "m4"
148 int method_unique_id = 1;
153 filebase = replace_sep (((Class *)class)->otype, file_sep);
154 gob_strdown (filebase);
156 if (output_dir != NULL && output_dir[0] != '\0') {
157 fullfilebase = g_strdup_printf("%s%c%s", output_dir,
158 G_DIR_SEPARATOR, filebase);
160 fullfilebase = g_strdup (filebase);
163 funcbase = replace_sep (((Class *)class)->otype, '_');
164 gob_strdown (funcbase);
166 pfuncbase = replace_sep (((Class *)class)->ptype, '_');
167 gob_strdown (pfuncbase);
169 macrobase = replace_sep (((Class *)class)->otype, '_');
170 gob_strup (macrobase);
172 macrois = make_pre_macro (((Class *)class)->otype, "IS");
173 pmacrois = make_pre_macro (((Class *)class)->ptype, "IS");
175 macrotype = make_pre_macro (((Class *)class)->otype, "TYPE");
176 pmacrotype = make_pre_macro (((Class *)class)->ptype, "TYPE");
178 typebase = remove_sep (((Class *)class)->otype);
180 ptypebase = remove_sep (((Class *)class)->ptype);
184 get_gtk_doc (const char *id)
191 val = g_hash_table_lookup(gtk_doc_hash, id);
193 return g_strdup_printf("/**\n * %s_%s:\n%s **/\n",
195 val = g_hash_table_lookup(gtk_doc_hash, id);
197 return g_strdup_printf("/**\n * %s_%s:\n%s **/\n",
203 print_type(FILE *fp, const Type *t, gboolean postfix_to_stars)
207 s = get_type(t, postfix_to_stars);
208 out_printf(fp, "%s", s);
214 print_method (FILE *fp,
215 const char *typeprefix,
216 const char *nameprefix,
217 const char *subnameprefix,
218 const char *namepostfix,
219 const char *afterargs,
222 gboolean print_funcattrs,
223 gboolean one_arg_per_line,
224 gboolean no_funcbase,
225 gboolean kill_underscore,
226 gboolean first_unused,
232 out_printf(fp, "%s", typeprefix);
233 print_type(fp, m->mtype, TRUE);
238 out_printf(fp, "%s%s%s%s(",
239 nameprefix, subnameprefix, id, namepostfix);
241 out_printf(fp, "%s%s_%s%s%s(",
242 nameprefix, funcbase, subnameprefix, id,
246 for(li=m->args; li; li=g_list_next(li)) {
247 FuncArg *arg = li->data;
248 const char *unused = "";
251 ! for_cpp && /* g++ has a cow with this */
254 unused = " G_GNUC_UNUSED";
257 print_type(fp, arg->atype, FALSE);
259 out_printf (fp, "___fake___");
261 out_printf(fp, "%s%s%s,%s", arg->name,
262 arg->atype->postfix ?
263 arg->atype->postfix : "",
265 one_arg_per_line ? "\n\t\t\t\t\t" : " ");
267 out_printf(fp, "%s%s%s", arg->name,
268 arg->atype->postfix ?
269 arg->atype->postfix : "",
273 out_printf(fp, ",%s...",
274 one_arg_per_line ? "\n\t\t\t\t\t" : " ");
276 out_printf(fp, "void");
278 /* Slightly icky: sometimes we are called st m->funcattrs
279 hasn't been set, but if so it should be NULL since its been
281 if(print_funcattrs && m->funcattrs != NULL
282 && strlen(m->funcattrs) > 0) {
283 /* To keep the output neat, we trim off the trailing '\n'
284 from the end of funcattrs for a moment. */
285 size_t funcattrs_len = strlen(m->funcattrs);
286 gboolean funcattrs_chomped = FALSE;
287 if((m->funcattrs)[funcattrs_len - 1] == '\n') {
288 m->funcattrs[funcattrs_len - 1] = '\0';
289 funcattrs_chomped = TRUE;
291 out_printf(fp, "%s)\n%s%s", afterargs, m->funcattrs, postfix);
292 /* Put it back like it was (though it shouldn't matter). */
293 if (funcattrs_chomped) {
294 (m->funcattrs)[funcattrs_len - 1] = '\n';
298 out_printf(fp, "%s)%s", afterargs, postfix);
303 any_method_to_alias(Class *c)
307 for(li=c->nodes;li;li=g_list_next(li)) {
308 Node *node = li->data;
309 if(node->type == METHOD_NODE) {
310 Method *m = (Method *)node;
312 if(m->method == INIT_METHOD ||
313 m->method == CLASS_INIT_METHOD ||
314 m->method == CONSTRUCTOR_METHOD ||
315 m->method == DISPOSE_METHOD ||
316 m->method == FINALIZE_METHOD ||
317 m->method == OVERRIDE_METHOD)
328 make_method_aliases (Class *c)
332 for(li = c->nodes; li != NULL; li = li->next) {
333 Node *node = li->data;
334 if(node->type == METHOD_NODE) {
335 Method *m = (Method *)node;
337 if(m->method == INIT_METHOD ||
338 m->method == CLASS_INIT_METHOD ||
339 m->method == CONSTRUCTOR_METHOD ||
340 m->method == DISPOSE_METHOD ||
341 m->method == FINALIZE_METHOD ||
342 m->method == OVERRIDE_METHOD)
345 out_printf (out, "#define self_%s %s_%s\n",
354 add_bad_hack_to_avoid_unused_warnings(const Class *c)
358 /* if we haven't had any methods, just return */
363 out_printf(out, "\n\n#if (!defined __GNUC__) || (defined __GNUC__ && defined __STRICT_ANSI__)\n");
365 "/*REALLY BAD HACK\n"
366 " This is to avoid unused warnings if you don't call\n"
367 " some method. I need to find a better way to do\n"
368 " this, not needed in GCC since we use some gcc\n"
369 " extentions to make saner, faster code */\n"
371 "___%s_really_bad_hack_to_avoid_warnings(void)\n"
373 out_printf(out, "\t((void (*)(void))GET_NEW_VARG)();\n");
374 for(li=c->nodes;li;li=g_list_next(li)) {
375 Node *node = li->data;
376 if(node->type == METHOD_NODE) {
377 Method *m = (Method *)node;
379 if(m->method == INIT_METHOD ||
380 m->method == CLASS_INIT_METHOD ||
381 m->method == CONSTRUCTOR_METHOD ||
382 m->method == DISPOSE_METHOD ||
383 m->method == FINALIZE_METHOD ||
384 m->method == OVERRIDE_METHOD)
387 /* in C++ mode we don't alias new */
388 if(for_cpp && strcmp(m->id, "new")==0)
391 out_printf(out, "\t((void (*)(void))self_%s)();\n", m->id);
394 out_printf(out, "\t___%s_really_bad_hack_to_avoid_warnings();\n",
397 out_printf(out, "}\n#endif /* !__GNUC__ || (__GNUC__ && __STRICT_ANSI__) */\n\n");
399 out_printf(out, "}\n\n");
403 put_variable(const Variable *v, FILE *fp)
405 out_printf(fp, "\t");
406 print_type(fp, v->vtype, FALSE);
407 out_printf(fp, "%s%s;", v->id,
409 v->vtype->postfix:"");
410 if(v->scope == PROTECTED_SCOPE)
411 out_printf(fp, " /* protected */");
412 out_printf(fp, "\n");
416 put_vs_method(const Method *m)
418 if(m->method != SIGNAL_LAST_METHOD &&
419 m->method != SIGNAL_FIRST_METHOD &&
420 m->method != VIRTUAL_METHOD)
423 /* if a signal mark it as such */
424 if(m->method != VIRTUAL_METHOD)
425 print_method(outh, "\t/*signal*/", "(* ", "", ") ", "", ";\n",
426 m, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE);
428 print_method(outh, "\t", "(* ", "", ") ", "", ";\n",
429 m, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE);
434 put_pub_method(const Method *m)
436 if(m->scope != PUBLIC_SCOPE)
439 out_addline_infile(outh, m->line_no);
440 print_method(outh, "", "\t", "", "\t", "", ";\n", m,
441 TRUE, TRUE, FALSE, TRUE, FALSE, FALSE);
442 out_addline_outfile(outh);
446 put_signal_macro (const Method *m, gboolean gnu)
448 if(m->method != SIGNAL_LAST_METHOD &&
449 m->method != SIGNAL_FIRST_METHOD)
454 out_printf (outh, "#define %s_connect__%s(object,func,data)\t"
455 "g_signal_connect(%s(object),\"%s\","
456 "(GCallback)(func),(data))\n",
457 funcbase, m->id, macrobase, m->id);
460 out_printf (outh, "#define %s_connect_after__%s(object,func,data)\t"
461 "g_signal_connect_after(%s(object),\"%s\","
462 "(GCallback)(func),(data))\n",
463 funcbase, m->id, macrobase, m->id);
466 out_printf (outh, "#define %s_connect_data__%s"
467 "(object,func,data,destroy_data,flags)\t"
468 "g_signal_connect_data(%s(object),\"%s\","
469 "(GCallback)(func),(data),(destroy_data),(GConnectFlags)(flags))\n",
470 funcbase, m->id, macrobase, m->id);
473 out_printf (outh, "#define %s_connect__%s(object,func,data)\t"
475 "%s(__extension__ ({%s *___object = (object); ___object; })),"
477 "(GCallback) __extension__ ({",
478 funcbase, m->id, macrobase, typebase, m->id);
479 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
480 " = (func); ", m, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE);
481 out_printf (outh, "___%s; }), (data))\n", m->id);
484 out_printf (outh, "#define %s_connect_after__%s(object,func,data)\t"
485 "g_signal_connect_after("
486 "%s(__extension__ ({%s *___object = (object); ___object; })),"
488 "(GCallback) __extension__ ({",
489 funcbase, m->id, macrobase, typebase, m->id);
490 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
491 " = (func); ", m, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE);
492 out_printf (outh, "___%s; }), (data))\n", m->id);
495 out_printf (outh, "#define %s_connect_data__%s"
496 "(object,func,data,destroy_data,flags)\t"
497 "g_signal_connect_data("
498 "%s(__extension__ ({%s *___object = (object); ___object; })),"
500 "(GCallback) __extension__ ({",
501 funcbase, m->id, macrobase, typebase, m->id);
502 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
503 " = (func); ", m, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE);
504 out_printf (outh, "___%s; }), (data), (destroy_data), (GConnectFlags)(flags))\n", m->id);
509 put_signal_macros (const Class *c, gboolean gnu)
516 for (li = c->nodes; li != NULL; li = li->next) {
517 const Node *n = li->data;
518 if (n->type == METHOD_NODE)
519 put_signal_macro ((Method *)n, gnu);
524 put_local_signal_macro (const Method *m)
526 if(m->method != SIGNAL_LAST_METHOD &&
527 m->method != SIGNAL_FIRST_METHOD)
531 out_printf (out, "#define self_connect__%s(object,func,data)\t"
532 "%s_connect__%s((object),(func),(data))\n",
533 m->id, funcbase, m->id);
536 out_printf (out, "#define self_connect_after__%s(object,func,data)\t"
537 "%s_connect_after__%s((object),(func),(data))\n",
538 m->id, funcbase, m->id);
541 out_printf (out, "#define self_connect_data__%s(object,func,data,destroy_data,flags)\t"
542 "%s_connect_data__%s((object),(func),(data),(destroy_data),(flags))\n",
543 m->id, funcbase, m->id);
547 put_local_signal_macros (const Class *c)
554 for (li = c->nodes; li != NULL; li = li->next) {
555 const Node *n = li->data;
556 if (n->type == METHOD_NODE)
557 put_local_signal_macro ((Method *)n);
563 put_prot_method(const Method *m)
567 if(m->scope != PROTECTED_SCOPE)
570 f = outph ? outph : out;
572 out_addline_infile(f, m->line_no);
573 print_method(f, "", "\t", "", "\t", "", ";\n",
574 m, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE);
575 out_addline_outfile(f);
579 put_priv_method_prot(const Method *m)
581 if(m->method == SIGNAL_LAST_METHOD ||
582 m->method == SIGNAL_FIRST_METHOD ||
583 m->method == VIRTUAL_METHOD) {
586 "static ", "___real_", "", " ", "", ";\n",
587 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
589 /* no else, here, it might still have a private prototype, it's not
592 if((m->method == OVERRIDE_METHOD &&
595 char *s = g_strdup_printf("___%x_", (guint)m->unique_id);
597 out_addline_infile(out, m->line_no);
598 print_method(out, "static ", s, "", " ", "",
599 no_gnu?";\n":" G_GNUC_UNUSED;\n",
600 m, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE);
602 out_addline_outfile(out);
604 } else if(m->scope == PRIVATE_SCOPE ||
605 m->method == INIT_METHOD ||
606 m->method == CLASS_INIT_METHOD ||
607 m->method == CONSTRUCTOR_METHOD ||
608 m->method == DISPOSE_METHOD ||
609 m->method == FINALIZE_METHOD) {
611 out_addline_infile(out, m->line_no);
612 print_method(out, "static ", "", "", " ", "",
613 no_gnu?";\n":" G_GNUC_UNUSED;\n",
614 m, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE);
616 out_addline_outfile(out);
621 make_func_arg (const char *typename, gboolean is_class, const char *name)
628 tn = g_strconcat (typename, ":Class", NULL);
630 tn = g_strdup (typename);
632 type = node_new (TYPE_NODE,
636 node = node_new (FUNCARG_NODE,
637 "atype:steal", (Type *)type,
640 return g_list_prepend (NULL, node);
644 make_inits(Class *cl)
646 int got_class_init = FALSE;
647 int got_init = FALSE;
650 for(li=cl->nodes;li;li=g_list_next(li)) {
652 if(n->type == METHOD_NODE) {
653 Method *m = (Method *)n;
654 if(m->method == INIT_METHOD) {
656 error_print(GOB_ERROR, m->line_no, "init defined more then once");
658 } else if(m->method == CLASS_INIT_METHOD) {
660 error_print(GOB_ERROR, m->line_no, "class_init defined more then once");
661 got_class_init = TRUE;
665 if(!got_class_init) {
666 Type *type = (Type *)node_new (TYPE_NODE,
669 node = node_new (METHOD_NODE,
671 "method", CLASS_INIT_METHOD,
674 "args:steal", make_func_arg (cl->otype,
677 "unique_id", method_unique_id++,
679 cl->nodes = g_list_prepend(cl->nodes, node);
682 Type *type = (Type *)node_new (TYPE_NODE,
685 node = node_new (METHOD_NODE,
687 "method", INIT_METHOD,
690 "args:steal", make_func_arg (cl->otype,
691 FALSE /* is_class */,
693 "unique_id", method_unique_id++,
695 cl->nodes = g_list_prepend(cl->nodes, node);
700 find_method(const Class *cl, int method, const char *id)
704 for(li=cl->nodes;li;li=g_list_next(li)) {
706 if(n->type == METHOD_NODE) {
707 Method *m = (Method *)n;
708 if (m->method == method
709 && (id == NULL || strcmp(m->id, id)==0))
718 find_constructor(const Class *cl)
720 user_constructor = find_method(cl, CONSTRUCTOR_METHOD, NULL);
724 find_dispose(const Class *cl)
726 dispose_handler = find_method(cl, OVERRIDE_METHOD, "dispose");
727 if (dispose_handler != NULL) {
728 if(strcmp(dispose_handler->otype, "G:Object") != 0)
729 error_print(GOB_ERROR, dispose_handler->line_no,
730 "dispose method override "
731 "of class other then "
733 if(g_list_length(dispose_handler->args) != 1)
734 error_print(GOB_ERROR, dispose_handler->line_no,
735 "dispose method override "
736 "with more then one "
740 user_dispose_method = find_method(cl, DISPOSE_METHOD, NULL);
744 find_finalize(const Class *cl)
746 finalize_handler = find_method(cl, OVERRIDE_METHOD, "finalize");
747 if (finalize_handler != NULL) {
748 if(strcmp(finalize_handler->otype, "G:Object") != 0)
749 error_print(GOB_ERROR, finalize_handler->line_no,
750 "finalize method override "
751 "of class other then "
753 if(g_list_length(finalize_handler->args) != 1)
754 error_print(GOB_ERROR, finalize_handler->line_no,
755 "finalize method override "
756 "with more then one "
760 user_finalize_method = find_method(cl, FINALIZE_METHOD, NULL);
764 /* hash of method -> name of signal prototype */
765 static GHashTable *marsh = NULL;
767 /* list of methods with different signal prototypes,
768 we check this list if we can use a signal prototype of a
769 previous signal method, there are only uniques here */
770 static GList *eq_signal_methods = NULL;
772 /* compare a list of strings */
774 is_list_equal(const GList *a, const GList *b)
776 for(;a && b; a=a->next, b=b->next) {
777 if(strcmp(a->data, b->data)!=0) {
781 /* the the lists were different length */
788 find_same_type_signal(const Method *m)
791 for(li=eq_signal_methods;li;li=li->next) {
792 Method *mm = li->data;
793 if(is_list_equal(mm->gtktypes, m->gtktypes))
800 print_signal_marsal_args (const Method *m)
802 if (strcmp (m->gtktypes->next->data, "NONE") != 0) {
805 for (i = 0, li = m->gtktypes->next;
807 i++, li = li->next) {
810 if (strcmp (li->data, "UNICHAR") == 0)
811 /* hack because glib is braindamaged */
812 get_func = g_strdup ("g_value_get_uint");
813 else if (strncmp(li->data, "BOXED_", 6) == 0)
814 get_func = g_strdup ("g_value_get_boxed");
816 get_func = g_strdup_printf
817 ("g_value_get_%s", (char *)li->data);
819 gob_strdown (get_func);
820 out_printf (out, ",\n\t\t(%s) "
821 "%s (param_values + %d)",
822 get_cast (li->data, FALSE),
827 out_printf (out, ",\n\t\tdata2);\n");
832 add_signal_prots(Method *m)
838 gboolean ret_none = FALSE;
839 gboolean arglist_none = FALSE;
841 const char *unused = "";
843 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
844 unused = " G_GNUC_UNUSED";
847 if (m->method != SIGNAL_LAST_METHOD &&
848 m->method != SIGNAL_FIRST_METHOD)
852 marsh = g_hash_table_new(NULL, NULL);
854 g_assert (m->gtktypes->next != NULL);
856 ret_none = strcmp(m->gtktypes->data, "NONE") == 0;
857 arglist_none = strcmp(m->gtktypes->next->data, "NONE") == 0;
859 if (ret_none && arglist_none)
862 /* if we already did a signal prototype just use that */
863 mm = find_same_type_signal (m);
865 s = g_hash_table_lookup (marsh, mm);
866 g_hash_table_insert (marsh, m, s);
873 retcast = get_cast (m->gtktypes->data, FALSE);
875 s = g_strdup_printf("Sig%d", sig++);
877 g_hash_table_insert(marsh, m, s);
878 eq_signal_methods = g_list_prepend(eq_signal_methods, m);
880 /* we know that we'll know all the gtktypes (so get_cast can't fail) */
881 out_printf(out, "\ntypedef %s (*___%s) (%s *, ",
882 get_cast(m->gtktypes->data, FALSE), s, typebase);
884 if ( ! arglist_none) {
885 for (li = m->gtktypes->next; li != NULL; li = li->next)
886 out_printf (out, "%s, ", get_cast (li->data, FALSE));
888 out_printf (out, "gpointer);\n");
890 out_printf (out, "\nstatic void\n"
891 "___marshal_%s (GClosure *closure,\n"
892 "\tGValue *return_value%s,\n"
893 "\tguint n_param_values,\n"
894 "\tconst GValue *param_values,\n"
895 "\tgpointer invocation_hint%s,\n"
896 "\tgpointer marshal_data)\n"
903 out_printf (out, "\t%s v_return;\n", retcast);
905 out_printf (out, "\tregister ___%s callback;\n"
906 "\tregister GCClosure *cc = (GCClosure*) closure;\n"
907 "\tregister gpointer data1, data2;\n\n",
910 out_printf (out, "\tg_return_if_fail (n_param_values == %d);\n\n",
911 arglist_none ? 1 : g_list_length (m->gtktypes));
914 "\tif (G_CCLOSURE_SWAP_DATA (closure)) {\n"
915 "\t\tdata1 = closure->data;\n"
916 "\t\tdata2 = g_value_peek_pointer (param_values + 0);\n"
918 "\t\tdata1 = g_value_peek_pointer (param_values + 0);\n"
919 "\t\tdata2 = closure->data;\n"
922 out_printf (out, "\tcallback = (___%s) "
923 "(marshal_data != NULL ? marshal_data : cc->callback);"
927 out_printf (out, "\tcallback ((%s *)data1", typebase);
929 out_printf (out, "\tv_return = callback ((%s *)data1",
933 print_signal_marsal_args (m);
936 /* FIXME: This code is so fucking ugly it hurts */
937 gboolean take_ownership =
938 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
939 strcmp ((char *)m->gtktypes->data, "BOXED") == 0);
943 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
944 /* hack because glib is braindamaged */
945 set_func = g_strdup ("g_value_set_uint");
947 set_func = g_strdup_printf ("g_value_%s_%s",
950 (char *)m->gtktypes->data);
951 gob_strdown (set_func);
953 out_printf (out, "\n\t%s (return_value, v_return);\n",
958 if (no_gnu || for_cpp /* g++ has a cow with G_GNUC_UNUSED */) {
960 out_printf (out, "\n\treturn_value = NULL;\n");
961 out_printf (out, "\tinvocation_hint = NULL;\n");
964 out_printf (out, "}\n\n");
968 interface_type(const char *if_name)
970 char *rawtype = remove_sep(if_name);
971 char *end = "", *typename;
975 * EEEK! evil, we should have some sort of option
976 * to force this for arbitrary interfaces, since
977 * some are Class and some are Iface. Glib is shite
981 if (strcmp (rawtype, "GtkEditable") == 0
982 || strcmp (rawtype, "GTypePlugin") == 0)
986 /* We'll assume Iface is the standard ending */
990 /* GTK3 doesn't need Iface end */
994 typename = g_strconcat(rawtype, end, (char *)NULL);
1001 define_parent_interface_refs(Class *c)
1008 out_printf(out, "\n/* parent class interface implementations */\n");
1009 for (li = c->interfaces; li != NULL; li = li->next) {
1010 char *name = replace_sep(li->data, '_');
1011 char *type = interface_type(li->data);
1013 out_printf (out, "static %s *%s_parent_iface;\n", type, name);
1024 out_printf(out, "\n");
1026 out_printf(out, "enum {\n");
1027 for(li=c->nodes;li;li=g_list_next(li)) {
1029 if(n->type == METHOD_NODE) {
1030 Method *m = (Method *)n;
1031 if(m->method == SIGNAL_LAST_METHOD ||
1032 m->method == SIGNAL_FIRST_METHOD) {
1033 char *s = g_strdup(m->id);
1035 out_printf(out, "\t%s_SIGNAL,\n", s);
1040 out_printf(out, "\tLAST_SIGNAL\n};\n\n");
1042 if (set_properties > 0 ||
1043 get_properties > 0) {
1044 out_printf(out, "enum {\n\tPROP_0");
1045 for(li=c->nodes;li;li=g_list_next(li)) {
1047 if (n->type == PROPERTY_NODE) {
1048 Property *p = (Property *)n;
1049 char *s = g_strdup (p->name);
1051 out_printf (out, ",\n\tPROP_%s", s);
1053 } else if (n->type == ARGUMENT_NODE) {
1054 Argument *a = (Argument *)n;
1055 char *s = g_strdup(a->name);
1057 out_printf(out, ",\n\tPROP_%s", s);
1061 out_printf(out, "\n};\n\n");
1066 "static guint object_signals[LAST_SIGNAL] = {0};\n\n");
1068 out_printf(out, "/* pointer to the class of our parent */\n");
1069 out_printf(out, "static %sClass *parent_class = NULL;\n", ptypebase);
1070 define_parent_interface_refs(c);
1071 out_printf(out, "\n");
1075 add_interface_methods (Class *c, const char *interface)
1078 gboolean added_line = FALSE;
1080 for (li = c->nodes; li != NULL; li = li->next) {
1082 Method *m = (Method *)n;
1083 if (n->type != METHOD_NODE ||
1084 m->method == OVERRIDE_METHOD ||
1085 m->interface == NULL ||
1086 strcmp (m->interface, interface) != 0)
1089 if (m->line_no > 0) {
1090 out_addline_infile (out, m->line_no);
1092 } else if (m->line_no == 0 &&
1094 out_addline_outfile (out);
1097 out_printf (out, "\tiface->%s = self_%s;\n",
1101 out_addline_outfile (out);
1105 add_interface_inits(Class *c)
1109 if (c->interfaces == NULL)
1112 out_printf(out, "\n");
1114 for (li = c->interfaces; li != NULL; li = li->next) {
1115 char *name = replace_sep(li->data, '_');
1116 char *type = interface_type(li->data);
1118 out_printf(out, "static void\n"
1119 "___%s_init (%s *iface)\n"
1122 add_interface_methods(c, li->data);
1124 out_printf(out, "\t%s_parent_iface\n", name);
1125 out_printf(out, for_cpp ? "\t\t= (%s *)" : "\t\t= ", type);
1126 out_printf(out, "g_type_interface_peek_parent(iface);\n"
1135 add_interface_infos(Class *c, gboolean static_storage)
1139 for (li = c->interfaces; li; li = li->next) {
1140 char *name = replace_sep(li->data, '_');
1141 out_printf(out, "\t%sconst GInterfaceInfo %s_info = {\n"
1142 "\t\t(GInterfaceInitFunc) ___%s_init,\n"
1146 static_storage ? "static " : "",
1151 out_printf(out, "\n");
1155 define_add_interfaces(Class *c)
1162 out_printf(out, "static void ___add_interfaces(GType type)\n{\n");
1163 add_interface_infos(c, TRUE);
1165 for (li = c->interfaces; li; li = li->next) {
1166 char *type = make_pre_macro(li->data, "TYPE");
1167 char *name = replace_sep(li->data, '_');
1169 out_printf(out, "\tg_type_add_interface_static\n"
1180 out_printf(out, "}\n\n");
1184 define_dynamic_add_interfaces(Class *c)
1191 out_printf(out, "static void ___add_interfaces"
1192 "(GTypeModule *type_module, GType type)\n"
1194 add_interface_infos(c, FALSE);
1197 * Hack to work around bug in g_type_module_add_interface,
1198 * which will fail to add an interface to types that derive
1199 * from something that also implements the same interface.
1201 * The actual GType system does not have any such problem,
1202 * and the GTypeModule implementation details relied upon
1203 * here have not changed once since the feature was first
1204 * implemented almost 20 years ago.
1206 out_printf(out, "\tstruct _ModuleInterfaceInfo {\n"
1207 "\t\tgboolean loaded;\n"
1208 "\t\tGType instance_type;\n"
1209 "\t\tGType interface_type;\n"
1210 "\t\tGInterfaceInfo info;\n"
1213 for (li = c->interfaces; li; li = li->next) {
1214 char *type = make_pre_macro(li->data, "TYPE");
1215 char *name = replace_sep(li->data, '_');
1217 out_printf(out, "\n"
1218 "\tmodinfo = g_malloc(sizeof *modinfo);\n"
1219 "\tmodinfo->loaded = TRUE;\n"
1220 "\tmodinfo->instance_type = type;\n"
1221 "\tmodinfo->interface_type = %s;\n"
1222 "\tmodinfo->info = %s_info;\n"
1223 "\tg_type_add_interface_dynamic\n"
1224 "\t\t( modinfo->instance_type\n"
1225 "\t\t, modinfo->interface_type\n"
1226 "\t\t, G_TYPE_PLUGIN(type_module)\n"
1228 "\ttype_module->interface_infos = g_slist_prepend\n"
1229 "\t\t( type_module->interface_infos\n"
1238 out_printf(out, "}\n\n");
1241 static void define_add_privates(Class *c)
1243 const char *addprivate = c->dynamic
1244 ? "G_ADD_PRIVATE_DYNAMIC"
1250 out_printf(out, "#ifdef %s\n"
1251 "#define ___add_privates() %s(%s)\n"
1253 "#define ___add_privates()\n"
1255 addprivate, addprivate, typebase);
1258 static void add_type_info(void)
1260 out_printf(out, "\tstatic const GTypeInfo info = {\n"
1261 "\t\tsizeof (%sClass),\n"
1262 "\t\t(GBaseInitFunc) NULL,\n"
1263 "\t\t(GBaseFinalizeFunc) NULL,\n"
1264 "\t\t(GClassInitFunc) %s_class_init,\n"
1265 "\t\t(GClassFinalizeFunc) NULL,\n"
1266 "\t\tNULL /* class_data */,\n"
1267 "\t\tsizeof (%s),\n"
1268 "\t\t%d /* n_preallocs */,\n"
1269 "\t\t(GInstanceInitFunc) %s_init,\n"
1272 typebase, funcbase, typebase, prealloc, funcbase);
1278 Class *c = (Class *)class;
1280 define_add_interfaces(c);
1281 define_add_privates(c);
1283 out_printf(out, "#ifdef G_DEFINE_TYPE_EXTENDED\n\n"
1284 "G_DEFINE_TYPE_EXTENDED(%s, %s, %s,\n"
1285 "\t(GTypeFlags)%s,\n",
1286 typebase, funcbase, pmacrotype,
1287 c->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0");
1290 out_printf(out, "\t___add_privates();\n");
1293 out_printf(out, "\t___add_interfaces(g_define_type_id);\n");
1295 /* Fallback for GLib < 2.4 */
1296 out_printf(out, ");\n\n"
1298 "GType %s_get_type(void)\n"
1300 "\tstatic GType type = 0;\n",
1305 out_printf(out, "\tif ___GOB_UNLIKELY(type == 0) {\n"
1306 "\t\ttype = g_type_register_static\n"
1310 "\t\t\t, (GTypeFlags)%s\n"
1312 pmacrotype, typebase,
1313 c->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0");
1316 out_printf(out, "\t\t___add_interfaces(type);\n");
1318 out_printf(out, "\t}\n\n"
1325 add_dynamic_get_type(void)
1327 Class *c = (Class *)class;
1329 define_dynamic_add_interfaces(c);
1330 define_add_privates(c);
1333 * G_DEFINE_DYNAMIC_TYPE_EXTENDED is usable if available, except for
1334 * some reason it defines an xxx_register_type function with internal
1335 * linkage. This is kind of weird so we have to work around that.
1337 out_printf(out, "#ifdef G_DEFINE_DYNAMIC_TYPE_EXTENDED\n\n"
1338 "static void %s_class_finalize(%sClass *c) { }\n\n"
1339 "#define %s_register_type ___register_type\n",
1340 funcbase, typebase, funcbase);
1342 out_printf(out, "G_DEFINE_DYNAMIC_TYPE_EXTENDED(%s, %s, %s,\n"
1343 "\t(GTypeFlags)%s,\n",
1344 typebase, funcbase, pmacrotype,
1345 c->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0");
1348 out_printf(out, "\t___add_privates();\n");
1350 if (c->interfaces) {
1351 out_printf(out, "\t___add_interfaces"
1352 "(type_module, %s_type_id);\n", funcbase);
1355 out_printf(out, ");\n"
1356 "#undef %s_register_type\n\n"
1357 "void %s_register_type(GTypeModule *type_module)\n"
1359 "\t___register_type(type_module);\n"
1361 funcbase, funcbase);
1363 /* Fallback for GLib < 2.14 */
1364 out_printf(out, "#else\n\n"
1365 "static GType %s_type_id;\n\n"
1366 "GType %s_get_type(void)\n"
1368 "\treturn %s_type_id;\n"
1370 funcbase, funcbase, funcbase);
1372 out_printf(out, "void %s_register_type(GTypeModule *type_module)\n"
1378 out_printf(out, "\t%s_type_id = g_type_module_register_type\n"
1379 "\t\t( type_module\n"
1383 "\t\t, (GTypeFlags)%s\n"
1385 funcbase, pmacrotype, typebase,
1386 c->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0");
1388 if (c->interfaces) {
1389 out_printf(out, "\t___add_interfaces"
1390 "(type_module, %s_type_id);\n",
1394 out_printf(out, "}\n\n"
1399 add_bonobo_object_get_type(void)
1401 Class *c = (Class *)class;
1403 define_add_interfaces(c);
1405 out_printf (out, "GType %s_get_type(void)\n"
1407 "\tstatic GType type = 0;\n",
1412 out_printf (out, "\tif ___GOB_UNLIKELY(type == 0) {\n"
1413 "\t\ttype = bonobo_type_unique\n"
1414 "\t\t\t( BONOBO_OBJECT_TYPE\n"
1415 "\t\t\t, POA_%s__init, NULL\n"
1416 "\t\t\t, G_STRUCT_OFFSET (%sClass, _epv)\n"
1420 c->bonobo_object_class, typebase, typebase);
1422 if (((Class *)class)->interfaces)
1423 out_printf(out, "\t\t___add_interfaces(type);\n");
1425 out_printf(out, "\t}\n\n"
1431 add_overrides(Class *c, const char *oname,
1432 gboolean did_base_obj)
1438 done = g_hash_table_new (g_str_hash, g_str_equal);
1440 s = g_strdup ("GObject");
1441 g_hash_table_insert (done, s, s);
1443 for (li = c->nodes; li != NULL; li = li->next) {
1446 Method *m = (Method *)n;
1447 if(n->type != METHOD_NODE ||
1448 m->method != OVERRIDE_METHOD)
1451 s = remove_sep(m->otype);
1453 if(g_hash_table_lookup(done, s)) {
1457 g_hash_table_insert(done, s, s);
1459 f = replace_sep(m->otype, '_');
1462 out_printf(out, "\t%sClass *%s_class = (%sClass *)%s;\n",
1467 g_hash_table_foreach (done, (GHFunc)g_free, NULL);
1468 g_hash_table_destroy (done);
1472 make_run_signal_flags(Method *m, gboolean last)
1487 gs = g_string_new(NULL);
1490 g_string_assign(gs, "G_SIGNAL_RUN_LAST");
1492 g_string_assign(gs, "G_SIGNAL_RUN_FIRST");
1494 if(m->scope == PUBLIC_SCOPE)
1495 g_string_append(gs, " | G_SIGNAL_ACTION");
1497 for(li = m->flags; li; li = li->next) {
1498 char *flag = li->data;
1500 for(i=0;flags[i];i++) {
1501 if(strcmp(flags[i], flag)==0)
1504 /* if we haven't found it in our list */
1506 error_printf(GOB_WARN, m->line_no,
1507 "Unknown flag '%s' used, "
1508 "perhaps it was misspelled",
1511 g_string_append_printf(gs, " | G_SIGNAL_%s", flag);
1515 char *ret = gs->str;
1516 g_string_free(gs, FALSE);
1523 add_signals(Class *c)
1527 out_printf(out, "\n");
1528 for(li=c->nodes;li;li=g_list_next(li)) {
1530 char *mar, *sig, *flags;
1531 gboolean is_none, last = FALSE;
1532 Method *m = (Method *)n;
1534 if(n->type != METHOD_NODE ||
1535 (m->method != SIGNAL_FIRST_METHOD &&
1536 m->method != SIGNAL_LAST_METHOD))
1539 if(m->method == SIGNAL_FIRST_METHOD)
1544 if(g_hash_table_lookup(marsh, m))
1545 mar = g_strconcat("___marshal_",
1546 (char *)g_hash_table_lookup(marsh, m),
1549 mar = g_strdup("g_cclosure_marshal_VOID__VOID");
1551 is_none = (strcmp(m->gtktypes->next->data, "NONE")==0);
1553 sig = g_strdup (m->id);
1555 flags = make_run_signal_flags (m, last);
1556 out_printf (out, "\tobject_signals[%s_SIGNAL] =\n"
1557 "\t\tg_signal_new (%s,\n"
1558 "\t\t\tG_TYPE_FROM_CLASS (g_object_class),\n"
1559 "\t\t\t(GSignalFlags)(%s),\n"
1560 "\t\t\tG_STRUCT_OFFSET (%sClass, %s),\n"
1561 "\t\t\tNULL, NULL,\n"
1563 "\t\t\tG_TYPE_%s, %d",
1564 sig, m->signal_name /*m->id* if not given signal_name*/,
1566 typebase, m->id, mar,
1567 (char *)m->gtktypes->data,
1568 is_none ? 0 : g_list_length(m->gtktypes->next));
1576 for(l = m->gtktypes->next; l != NULL; l = l->next) {
1577 char *str = l->data;
1578 if (strncmp (str, "BOXED_", 6) == 0)
1579 t = g_strdup (&(str[6]));
1581 t = g_strconcat ("G_TYPE_", str, NULL);
1582 out_printf (out, ",\n\t\t\t%s", t);
1587 out_printf(out, ");\n");
1589 if(strcmp(m->gtktypes->data, "NONE") != 0 ||
1592 out_printf(out, "\tif ___GOB_UNLIKELY(");
1593 if(strcmp(m->gtktypes->data, "NONE") != 0) {
1594 out_printf(out, "sizeof(");
1595 print_type(out, m->mtype, FALSE);
1596 out_printf(out, "%s",
1598 m->mtype->postfix : "");
1599 out_printf(out, ") != sizeof(%s) || ",
1600 get_cast(m->gtktypes->data, FALSE));
1603 for(al = m->args->next, gl = m->gtktypes->next;
1604 al != NULL && gl != NULL;
1605 al = al->next, gl = gl->next) {
1606 FuncArg *arg = al->data;
1607 char *gtkarg = gl->data;
1609 out_printf(out, "sizeof(");
1610 print_type(out, arg->atype, FALSE);
1611 out_printf(out, "%s",
1612 arg->atype->postfix ?
1613 arg->atype->postfix : "");
1614 out_printf(out, ") != sizeof(%s) || ",
1615 get_cast(gtkarg, FALSE));
1619 "parent_class == NULL /* avoid warning */");
1621 out_printf(out, ") {\n"
1622 "\t\tg_error(\"%s line %d: Type mismatch "
1623 "of \\\"%s\\\" signal signature\");\n"
1625 filename, m->line_no, m->id);
1632 set_def_handlers(Class *c, const char *oname)
1635 gboolean set_line = FALSE;
1637 out_printf(out, "\n");
1638 for(li = c->nodes; li; li = g_list_next(li)) {
1640 Method *m = (Method *)n;
1642 if(n->type != METHOD_NODE ||
1643 (m->method != SIGNAL_FIRST_METHOD &&
1644 m->method != SIGNAL_LAST_METHOD &&
1645 m->method != VIRTUAL_METHOD &&
1646 m->method != OVERRIDE_METHOD))
1649 if(m->line_no > 0 && m->cbuf) {
1650 out_addline_infile(out, m->line_no);
1652 } else if(set_line) {
1653 out_addline_outfile(out);
1658 if (m->method == OVERRIDE_METHOD) {
1660 s = replace_sep (m->otype, '_');
1664 dispose_handler != NULL &&
1665 strcmp (m->id, "dispose") == 0)
1666 out_printf (out, "\tg_object_class->dispose "
1668 else if (need_finalize &&
1670 strcmp(m->id, "finalize") == 0)
1672 "\tg_object_class->finalize = ___finalize;\n");
1673 else if (m->cbuf != NULL)
1675 "\t%s_class->%s = ___%x_%s_%s;\n",
1676 s, m->id, (guint)m->unique_id,
1679 out_printf(out, "\t%s_class->%s = NULL;\n",
1683 out_printf(out, "\t%s->%s = ___real_%s_%s;\n",
1687 out_printf(out, "\t%s->%s = NULL;\n",
1692 out_addline_outfile(out);
1696 make_argument (Argument *a)
1701 char *argflags[] = {
1709 flags = g_string_new ("(GParamFlags)(");
1711 if(a->get && a->set)
1712 g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
1714 g_string_append (flags, "G_PARAM_READABLE");
1716 g_string_append (flags, "G_PARAM_WRITABLE");
1718 g_assert(a->get || a->set);
1720 for (l = a->flags; l != NULL; l = l->next) {
1721 char *flag = l->data;
1723 if(strcmp (flag, "READABLE") == 0 ||
1724 strcmp (flag, "WRITABLE") == 0) {
1725 error_print(GOB_WARN, a->line_no,
1727 "WRITABLE argument flags are "
1728 "set automatically");
1731 for(i = 0; argflags[i]; i++) {
1732 if(strcmp(argflags[i], flag)==0)
1735 g_string_append_printf(flags, " | %s%s", argflags[i] ? "G_PARAM_" : "", flag);
1738 g_string_append (flags, ")");
1740 s = g_strdup(a->name);
1742 if (!strcmp (a->gtktype, "ENUM"))
1743 out_printf(out, "\tparam_spec = g_param_spec_enum (\"%s\", NULL, NULL,\n"
1744 "\t\tG_TYPE_ENUM, 0,\n"
1746 a->name, flags->str);
1747 if (!strcmp (a->gtktype, "FLAGS"))
1748 out_printf(out, "\tparam_spec = g_param_spec_flags (\"%s\", NULL, NULL,\n"
1749 "\t\tG_TYPE_FLAGS, 0,\n"
1751 a->name, flags->str);
1752 else if (!strcmp (a->gtktype, "OBJECT"))
1753 out_printf(out, "\tparam_spec = g_param_spec_object (\"%s\", NULL, NULL,\n"
1754 "\t\tG_TYPE_OBJECT,\n"
1756 a->name, flags->str);
1757 else if (!strcmp (a->gtktype, "STRING"))
1758 out_printf(out, "\tparam_spec = g_param_spec_string (\"%s\", NULL, NULL,\n"
1761 a->name, flags->str);
1762 else if (!strcmp (a->gtktype, "INT"))
1763 out_printf(out, "\tparam_spec = g_param_spec_int (\"%s\", NULL, NULL,\n"
1764 "\t\tG_MININT, G_MAXINT,\n"
1767 a->name, flags->str);
1768 else if (!strcmp (a->gtktype, "UINT"))
1769 out_printf(out, "\tparam_spec = g_param_spec_uint (\"%s\", NULL, NULL,\n"
1770 "\t\t0, G_MAXUINT,\n"
1773 a->name, flags->str);
1774 else if (!strcmp (a->gtktype, "INT"))
1775 out_printf(out, "\tparam_spec = g_param_spec_int (\"%s\", NULL, NULL,\n"
1776 "\t\tG_MININT, G_MAXINT,\n"
1779 a->name, flags->str);
1780 else if (!strcmp (a->gtktype, "CHAR"))
1781 out_printf(out, "\tparam_spec = g_param_spec_char (\"%s\", NULL, NULL,\n"
1785 a->name, flags->str);
1786 else if (!strcmp (a->gtktype, "UCHAR"))
1787 out_printf(out, "\tparam_spec = g_param_spec_uchar (\"%s\", NULL, NULL,\n"
1791 a->name, flags->str);
1792 else if (!strcmp (a->gtktype, "BOOL") ||
1793 !strcmp (a->gtktype, "BOOLEAN"))
1794 out_printf(out, "\tparam_spec = g_param_spec_boolean (\"%s\", NULL, NULL,\n"
1797 a->name, flags->str);
1798 else if (!strcmp (a->gtktype, "LONG"))
1799 out_printf(out, "\tparam_spec = g_param_spec_long (\"%s\", NULL, NULL,\n"
1800 "\t\tG_MINLONG, G_MAXLONG,\n"
1803 a->name, flags->str);
1804 else if (!strcmp (a->gtktype, "ULONG"))
1805 out_printf(out, "\tparam_spec = g_param_spec_ulong (\"%s\", NULL, NULL,\n"
1806 "\t\t0, G_MAXULONG,\n"
1809 a->name, flags->str);
1810 else if (!strcmp (a->gtktype, "INT64"))
1811 out_printf(out, "\tparam_spec = g_param_spec_int64 (\"%s\", NULL, NULL,\n"
1812 "\t\tG_MININT64, G_MAXINT64,\n"
1815 a->name, flags->str);
1816 else if (!strcmp (a->gtktype, "UINT64"))
1817 out_printf(out, "\tparam_spec = g_param_spec_uint64 (\"%s\", NULL, NULL,\n"
1818 "\t\t0, G_MAXUINT64,\n"
1821 a->name, flags->str);
1822 else if (!strcmp (a->gtktype, "FLOAT"))
1823 out_printf(out, "\tparam_spec = g_param_spec_float (\"%s\", NULL, NULL,\n"
1824 "\t\t-G_MAXFLOAT, G_MAXFLOAT,\n"
1827 a->name, flags->str);
1828 else if (!strcmp (a->gtktype, "DOUBLE"))
1829 out_printf(out, "\tparam_spec = g_param_spec_double (\"%s\", NULL, NULL,\n"
1830 "\t\t-G_MAXDOUBLE, G_MAXDOUBLE,\n"
1833 a->name, flags->str);
1834 else if (!strcmp (a->gtktype, "POINTER"))
1835 out_printf(out, "\tparam_spec = g_param_spec_pointer (\"%s\", NULL, NULL,\n"
1837 a->name, flags->str);
1839 error_printf (GOB_ERROR, a->line_no,
1840 "%s type is not supported for arguments, try using properties",
1843 out_printf(out, "\tg_object_class_install_property (g_object_class,\n"
1844 "\t\tPROP_%s, param_spec);\n", s);
1848 g_string_free(flags, TRUE);
1851 #define value_for_print(str, alt) (str != NULL ? str : alt)
1854 make_property (Property *p)
1858 if (p->get == NULL && p->set == NULL) {
1859 error_print (GOB_ERROR, p->line_no,
1860 "Property has no getter nor setter");
1864 if (p->flags != NULL)
1865 error_print (GOB_WARN, p->line_no,
1866 "Overridden property, flags ignored");
1867 if (p->nick != NULL)
1868 error_print (GOB_WARN, p->line_no,
1869 "Overridden property, nick ignored");
1870 if (p->blurb != NULL)
1871 error_print (GOB_WARN, p->line_no,
1872 "Overridden property, blurb ignored");
1873 if (p->minimum != NULL)
1874 error_print (GOB_WARN, p->line_no,
1875 "Overridden property, minimum ignored");
1876 if (p->maximum != NULL)
1877 error_print (GOB_WARN, p->line_no,
1878 "Overridden property, maximum ignored");
1879 if (p->default_value != NULL)
1880 error_print (GOB_WARN, p->line_no,
1881 "Overridden property, default_value ignored");
1883 s = g_strdup (p->name);
1885 out_printf (out, "\tg_object_class_override_property (g_object_class,\n"
1887 "\t\t\"%s\");\n", s, value_for_print (p->canonical_name, p->name) );
1892 char *argflags[] = {
1900 flags = g_string_new ("(GParamFlags)(");
1902 if (p->get != NULL && p->set != NULL)
1903 g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
1904 else if (p->get != NULL)
1905 g_string_append (flags, "G_PARAM_READABLE");
1907 g_string_append (flags, "G_PARAM_WRITABLE");
1910 for (l = p->flags; l != NULL; l = l->next) {
1911 char *flag = l->data;
1913 if(strcmp (flag, "READABLE") == 0 ||
1914 strcmp (flag, "WRITABLE") == 0) {
1915 error_print(GOB_WARN, p->line_no,
1917 "WRITABLE argument flags are "
1918 "set automatically");
1921 for(i = 0; argflags[i]; i++) {
1922 if(strcmp(argflags[i], flag)==0)
1925 g_string_append_printf(flags, " | %s%s", argflags[i] ? "G_PARAM_" : "", flag);
1928 g_string_append (flags, ")");
1930 if (strcmp (p->gtktype, "CHAR") == 0) {
1931 out_printf (out, "\tparam_spec = g_param_spec_char\n"
1932 "\t\t(\"%s\" /* name */,\n"
1933 "\t\t %s /* nick */,\n"
1934 "\t\t %s /* blurb */,\n"
1935 "\t\t %s /* minimum */,\n"
1936 "\t\t %s /* maximum */,\n"
1937 "\t\t %s /* default_value */,\n"
1939 value_for_print (p->canonical_name, p->name),
1940 value_for_print (p->nick, "NULL"),
1941 value_for_print (p->blurb, "NULL"),
1942 value_for_print (p->minimum, "-128"),
1943 value_for_print (p->maximum, "127"),
1944 value_for_print (p->default_value, "0"),
1946 } else if (strcmp (p->gtktype, "UCHAR") == 0) {
1947 out_printf (out, "\tparam_spec = g_param_spec_uchar\n"
1948 "\t\t(\"%s\" /* name */,\n"
1949 "\t\t %s /* nick */,\n"
1950 "\t\t %s /* blurb */,\n"
1951 "\t\t %s /* minimum */,\n"
1952 "\t\t %s /* maximum */,\n"
1953 "\t\t %s /* default_value */,\n"
1955 value_for_print (p->canonical_name, p->name),
1956 value_for_print (p->nick, "NULL"),
1957 value_for_print (p->blurb, "NULL"),
1958 value_for_print (p->minimum, "0"),
1959 value_for_print (p->maximum, "0xFF"),
1960 value_for_print (p->default_value, "0"),
1962 } else if (strcmp (p->gtktype, "BOOLEAN") == 0) {
1963 out_printf (out, "\tparam_spec = g_param_spec_boolean\n"
1964 "\t\t(\"%s\" /* name */,\n"
1965 "\t\t %s /* nick */,\n"
1966 "\t\t %s /* blurb */,\n"
1967 "\t\t %s /* default_value */,\n"
1969 value_for_print (p->canonical_name, p->name),
1970 value_for_print (p->nick, "NULL"),
1971 value_for_print (p->blurb, "NULL"),
1972 value_for_print (p->default_value, "FALSE"),
1974 } else if (strcmp (p->gtktype, "INT") == 0) {
1975 out_printf (out, "\tparam_spec = g_param_spec_int\n"
1976 "\t\t(\"%s\" /* name */,\n"
1977 "\t\t %s /* nick */,\n"
1978 "\t\t %s /* blurb */,\n"
1979 "\t\t %s /* minimum */,\n"
1980 "\t\t %s /* maximum */,\n"
1981 "\t\t %s /* default_value */,\n"
1983 value_for_print (p->canonical_name, p->name),
1984 value_for_print (p->nick, "NULL"),
1985 value_for_print (p->blurb, "NULL"),
1986 value_for_print (p->minimum, "G_MININT"),
1987 value_for_print (p->maximum, "G_MAXINT"),
1988 value_for_print (p->default_value, "0"),
1990 } else if (strcmp (p->gtktype, "UINT") == 0) {
1991 out_printf (out, "\tparam_spec = g_param_spec_uint\n"
1992 "\t\t(\"%s\" /* name */,\n"
1993 "\t\t %s /* nick */,\n"
1994 "\t\t %s /* blurb */,\n"
1995 "\t\t %s /* minimum */,\n"
1996 "\t\t %s /* maximum */,\n"
1997 "\t\t %s /* default_value */,\n"
1999 value_for_print (p->canonical_name, p->name),
2000 value_for_print (p->nick, "NULL"),
2001 value_for_print (p->blurb, "NULL"),
2002 value_for_print (p->minimum, "0"),
2003 value_for_print (p->maximum, "G_MAXUINT"),
2004 value_for_print (p->default_value, "0"),
2006 } else if (strcmp (p->gtktype, "LONG") == 0) {
2007 out_printf (out, "\tparam_spec = g_param_spec_long\n"
2008 "\t\t(\"%s\" /* name */,\n"
2009 "\t\t %s /* nick */,\n"
2010 "\t\t %s /* blurb */,\n"
2011 "\t\t %s /* minimum */,\n"
2012 "\t\t %s /* maximum */,\n"
2013 "\t\t %s /* default_value */,\n"
2015 value_for_print (p->canonical_name, p->name),
2016 value_for_print (p->nick, "NULL"),
2017 value_for_print (p->blurb, "NULL"),
2018 value_for_print (p->minimum, "G_MINLONG"),
2019 value_for_print (p->maximum, "G_MAXLONG"),
2020 value_for_print (p->default_value, "0"),
2022 } else if (strcmp (p->gtktype, "ULONG") == 0) {
2023 out_printf (out, "\tparam_spec = g_param_spec_ulong\n"
2024 "\t\t(\"%s\" /* name */,\n"
2025 "\t\t %s /* nick */,\n"
2026 "\t\t %s /* blurb */,\n"
2027 "\t\t %s /* minimum */,\n"
2028 "\t\t %s /* maximum */,\n"
2029 "\t\t %s /* default_value */,\n"
2031 value_for_print (p->canonical_name, p->name),
2032 value_for_print (p->nick, "NULL"),
2033 value_for_print (p->blurb, "NULL"),
2034 value_for_print (p->minimum, "0"),
2035 value_for_print (p->maximum, "G_MAXULONG"),
2036 value_for_print (p->default_value, "0"),
2038 } else if (strcmp (p->gtktype, "INT64") == 0) {
2039 out_printf (out, "\tparam_spec = g_param_spec_int64\n"
2040 "\t\t(\"%s\" /* name */,\n"
2041 "\t\t %s /* nick */,\n"
2042 "\t\t %s /* blurb */,\n"
2043 "\t\t %s /* minimum */,\n"
2044 "\t\t %s /* maximum */,\n"
2045 "\t\t %s /* default_value */,\n"
2047 value_for_print (p->canonical_name, p->name),
2048 value_for_print (p->nick, "NULL"),
2049 value_for_print (p->blurb, "NULL"),
2050 value_for_print (p->minimum, "G_MININT64"),
2051 value_for_print (p->maximum, "G_MAXINT64"),
2052 value_for_print (p->default_value, "0"),
2054 } else if (strcmp (p->gtktype, "UINT64") == 0) {
2055 out_printf (out, "\tparam_spec = g_param_spec_uint64\n"
2056 "\t\t(\"%s\" /* name */,\n"
2057 "\t\t %s /* nick */,\n"
2058 "\t\t %s /* blurb */,\n"
2059 "\t\t %s /* minimum */,\n"
2060 "\t\t %s /* maximum */,\n"
2061 "\t\t %s /* default_value */,\n"
2063 value_for_print (p->canonical_name, p->name),
2064 value_for_print (p->nick, "NULL"),
2065 value_for_print (p->blurb, "NULL"),
2066 value_for_print (p->minimum, "0"),
2067 value_for_print (p->maximum, "G_MAXUINT64"),
2068 value_for_print (p->default_value, "0"),
2070 } else if (strcmp (p->gtktype, "UNICHAR") == 0) {
2071 out_printf (out, "\tparam_spec = g_param_spec_unichar\n"
2072 "\t\t(\"%s\" /* name */,\n"
2073 "\t\t %s /* nick */,\n"
2074 "\t\t %s /* blurb */,\n"
2075 "\t\t %s /* default_value */,\n"
2077 value_for_print (p->canonical_name, p->name),
2078 value_for_print (p->nick, "NULL"),
2079 value_for_print (p->blurb, "NULL"),
2080 value_for_print (p->default_value, "0"),
2082 } else if (strcmp (p->gtktype, "ENUM") == 0) {
2083 char *type = make_me_type (p->extra_gtktype,
2085 out_printf (out, "\tparam_spec = g_param_spec_enum\n"
2086 "\t\t(\"%s\" /* name */,\n"
2087 "\t\t %s /* nick */,\n"
2088 "\t\t %s /* blurb */,\n"
2089 "\t\t %s /* enum_type */,\n"
2090 "\t\t %s /* default_value */,\n"
2092 value_for_print (p->canonical_name, p->name),
2093 value_for_print (p->nick, "NULL"),
2094 value_for_print (p->blurb, "NULL"),
2096 value_for_print (p->default_value, "0"),
2099 } else if (strcmp (p->gtktype, "FLAGS") == 0) {
2100 char *type = make_me_type (p->extra_gtktype,
2102 out_printf (out, "\tparam_spec = g_param_spec_flags\n"
2103 "\t\t(\"%s\" /* name */,\n"
2104 "\t\t %s /* nick */,\n"
2105 "\t\t %s /* blurb */,\n"
2106 "\t\t %s /* flags_type */,\n"
2107 "\t\t %s /* default_value */,\n"
2109 value_for_print (p->canonical_name, p->name),
2110 value_for_print (p->nick, "NULL"),
2111 value_for_print (p->blurb, "NULL"),
2113 value_for_print (p->default_value, "0"),
2116 } else if (strcmp (p->gtktype, "FLOAT") == 0) {
2117 out_printf (out, "\tparam_spec = g_param_spec_float\n"
2118 "\t\t(\"%s\" /* name */,\n"
2119 "\t\t %s /* nick */,\n"
2120 "\t\t %s /* blurb */,\n"
2121 "\t\t %s /* minimum */,\n"
2122 "\t\t %s /* maximum */,\n"
2123 "\t\t %s /* default_value */,\n"
2125 value_for_print (p->canonical_name, p->name),
2126 value_for_print (p->nick, "NULL"),
2127 value_for_print (p->blurb, "NULL"),
2128 value_for_print (p->minimum, "-G_MAXFLOAT"),
2129 value_for_print (p->maximum, "G_MAXFLOAT"),
2130 value_for_print (p->default_value, "0.0"),
2132 } else if (strcmp (p->gtktype, "DOUBLE") == 0) {
2133 out_printf (out, "\tparam_spec = g_param_spec_double\n"
2134 "\t\t(\"%s\" /* name */,\n"
2135 "\t\t %s /* nick */,\n"
2136 "\t\t %s /* blurb */,\n"
2137 "\t\t %s /* minimum */,\n"
2138 "\t\t %s /* maximum */,\n"
2139 "\t\t %s /* default_value */,\n"
2141 value_for_print (p->canonical_name, p->name),
2142 value_for_print (p->nick, "NULL"),
2143 value_for_print (p->blurb, "NULL"),
2144 value_for_print (p->minimum, "-G_MAXDOUBLE"),
2145 value_for_print (p->maximum, "G_MAXDOUBLE"),
2146 value_for_print (p->default_value, "0.0"),
2148 } else if (strcmp (p->gtktype, "STRING") == 0) {
2149 out_printf (out, "\tparam_spec = g_param_spec_string\n"
2150 "\t\t(\"%s\" /* name */,\n"
2151 "\t\t %s /* nick */,\n"
2152 "\t\t %s /* blurb */,\n"
2153 "\t\t %s /* default_value */,\n"
2155 value_for_print (p->canonical_name, p->name),
2156 value_for_print (p->nick, "NULL"),
2157 value_for_print (p->blurb, "NULL"),
2158 value_for_print (p->default_value, "NULL"),
2160 } else if (strcmp (p->gtktype, "PARAM") == 0) {
2161 char *type = make_me_type (p->extra_gtktype,
2163 out_printf (out, "\tparam_spec = g_param_spec_param\n"
2164 "\t\t(\"%s\" /* name */,\n"
2165 "\t\t %s /* nick */,\n"
2166 "\t\t %s /* blurb */,\n"
2167 "\t\t %s /* param_type */,\n"
2169 value_for_print (p->canonical_name, p->name),
2170 value_for_print (p->nick, "NULL"),
2171 value_for_print (p->blurb, "NULL"),
2175 } else if (strcmp (p->gtktype, "BOXED") == 0) {
2176 char *type = make_me_type (p->extra_gtktype,
2178 out_printf (out, "\tparam_spec = g_param_spec_boxed\n"
2179 "\t\t(\"%s\" /* name */,\n"
2180 "\t\t %s /* nick */,\n"
2181 "\t\t %s /* blurb */,\n"
2182 "\t\t %s /* boxed_type */,\n"
2184 value_for_print (p->canonical_name, p->name),
2185 value_for_print (p->nick, "NULL"),
2186 value_for_print (p->blurb, "NULL"),
2190 } else if (strcmp (p->gtktype, "POINTER") == 0) {
2191 out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
2192 "\t\t(\"%s\" /* name */,\n"
2193 "\t\t %s /* nick */,\n"
2194 "\t\t %s /* blurb */,\n"
2196 value_for_print (p->canonical_name, p->name),
2197 value_for_print (p->nick, "NULL"),
2198 value_for_print (p->blurb, "NULL"),
2200 /* FIXME: VALUE_ARRAY */
2201 } else if (strcmp (p->gtktype, "CLOSURE") == 0) {
2202 out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
2203 "\t\t(\"%s\" /* name */,\n"
2204 "\t\t %s /* nick */,\n"
2205 "\t\t %s /* blurb */,\n"
2207 value_for_print (p->canonical_name, p->name),
2208 value_for_print (p->nick, "NULL"),
2209 value_for_print (p->blurb, "NULL"),
2211 } else if (strcmp (p->gtktype, "OBJECT") == 0) {
2212 char *type = make_me_type (p->extra_gtktype,
2214 out_printf (out, "\tparam_spec = g_param_spec_object\n"
2215 "\t\t(\"%s\" /* name */,\n"
2216 "\t\t %s /* nick */,\n"
2217 "\t\t %s /* blurb */,\n"
2218 "\t\t %s /* object_type */,\n"
2220 value_for_print (p->canonical_name, p->name),
2221 value_for_print (p->nick, "NULL"),
2222 value_for_print (p->blurb, "NULL"),
2227 error_printf (GOB_ERROR, p->line_no,
2228 "%s type is not supported by properties",
2232 s = g_strdup (p->name);
2234 out_printf (out, "\tg_object_class_install_property (g_object_class,\n"
2236 "\t\tparam_spec);\n", s);
2239 g_string_free (flags, TRUE);
2244 make_arguments(Class *c)
2247 if (get_properties > 0)
2248 out_printf(out, "\tg_object_class->get_property = ___object_get_property;\n");
2249 if (set_properties > 0)
2250 out_printf(out, "\tg_object_class->set_property = ___object_set_property;\n");
2251 out_printf (out, " {\n");
2252 for (li = c->nodes; li != NULL; li = li->next) {
2254 if ((n->type == PROPERTY_NODE && ! ((Property *) n)->override)
2255 || n->type == ARGUMENT_NODE) {
2256 out_printf(out, "\tGParamSpec *param_spec;\n\n");
2261 for (li = c->nodes; li != NULL; li = li->next) {
2263 if (n->type == PROPERTY_NODE)
2264 make_property ((Property *)n);
2265 else if (n->type == ARGUMENT_NODE)
2266 make_argument ((Argument *)n);
2268 out_printf(out, " }\n");
2272 print_initializer(Method *m, Variable *v)
2279 if(v->initializer == NULL)
2282 if(v->scope == PRIVATE_SCOPE)
2283 root = g_strconcat(((FuncArg *)m->args->data)->name,
2286 root = g_strdup(((FuncArg *)m->args->data)->name);
2288 if(v->initializer_line > 0)
2289 out_addline_infile(out, v->initializer_line);
2291 if (v->initializer_simple)
2292 out_printf(out, "\t%s->%s = %s;\n",
2293 root, v->id, v->initializer);
2294 else if (strcmp(v->id, "_glade_xml") == 0)
2295 /* This is OK, this v->initializer string is set internally
2296 and it will eat exactly one string! */
2297 out_printf(out,v->initializer, ((FuncArg *)m->args->data)->name);
2299 out_printf(out, "%s", v->initializer);
2301 if(v->initializer_line > 0)
2302 out_addline_outfile(out);
2308 print_glade_widget(Method *m, Variable *v)
2313 if(!v->glade_widget)
2316 if(v->scope == PRIVATE_SCOPE)
2317 root = g_strconcat(((FuncArg *)m->args->data)->name,
2320 root = g_strdup(((FuncArg *)m->args->data)->name);
2322 cast = get_type(v->vtype, FALSE);
2323 out_printf(out, "\t%s->%s = (%s)glade_xml_get_widget(%s->_glade_xml, \"%s\");\n",
2324 root, v->id, cast, root, v->id);
2330 print_destructor (Variable *v)
2334 if(v->destructor == NULL)
2337 if(v->scope == PRIVATE_SCOPE)
2338 root = "self->_priv";
2342 if(v->destructor_simple) {
2343 if(v->destructor_line > 0)
2344 out_addline_infile(out, v->destructor_line);
2347 out_printf(out, "\tif(%s->%s) { "
2348 "(reinterpret_cast<void (*)(void *)>(%s)) ((gpointer)%s->%s); "
2349 "%s->%s = NULL; }\n",
2350 root, v->id, v->destructor, root, v->id,
2353 out_printf(out, "\tif(%s->%s) { "
2354 "%s ((gpointer) %s->%s); "
2355 "%s->%s = NULL; }\n",
2356 root, v->id, v->destructor, root, v->id,
2360 if(v->destructor_line > 0)
2361 out_addline_outfile(out);
2363 out_printf(out, "#define %s (%s->%s)\n", v->id, root, v->id);
2364 out_printf(out, "#define VAR %s\n", v->id);
2365 out_printf(out, "\t{\n");
2366 if(v->destructor_line > 0)
2367 out_addline_infile(out, v->destructor_line);
2369 out_printf(out, "\t%s}\n", v->destructor);
2371 if(v->destructor_line > 0)
2372 out_addline_outfile(out);
2373 out_printf(out, "\tmemset(&(%s), 0, sizeof(%s));\n",
2375 out_printf(out, "#undef VAR\n");
2376 out_printf(out, "#undef %s\n", v->id);
2381 add_constructor (Class *c)
2383 out_printf(out, "\nstatic GObject *\n"
2384 "___constructor (GType type, guint n_construct_properties, GObjectConstructParam *construct_properties)\n"
2387 "#define __GOB_FUNCTION__ \"%s::constructor\"\n",
2390 out_printf(out, "\tGObject *obj_self;\n");
2391 out_printf(out, "\t%s *self;\n", typebase);
2393 out_printf(out, "\tobj_self = G_OBJECT_CLASS (parent_class)->constructor (type, n_construct_properties, construct_properties);\n");
2394 out_printf(out, "\tself = %s (obj_self);\n", macrobase);
2396 if (user_constructor->line_no > 0)
2397 out_addline_infile (out, user_constructor->line_no);
2398 out_printf (out, "\t%s_constructor (self);\n", funcbase);
2399 if (user_constructor->line_no > 0)
2400 out_addline_outfile (out);
2402 out_printf(out, "\treturn obj_self;\n");
2403 out_printf(out, "}\n"
2404 "#undef __GOB_FUNCTION__\n\n");
2408 print_unreftors (Class *c)
2411 for(li = ((Class *)class)->nodes;
2415 Variable *v = (Variable *)n;
2416 if (n->type == VARIABLE_NODE &&
2417 v->scope != CLASS_SCOPE &&
2418 v->destructor_unref)
2419 print_destructor (v);
2424 add_dispose (Class *c)
2426 out_printf(out, "\nstatic void\n"
2427 "___dispose (GObject *obj_self)\n"
2430 "#define __GOB_FUNCTION__ \"%s::dispose\"\n",
2433 if (unreftors > 0 || user_dispose_method != NULL) {
2434 out_printf (out, "\t%s *self%s = %s (obj_self);\n",
2436 ! no_gnu ? " G_GNUC_UNUSED" : "",
2440 if (dispose_handler != NULL) {
2441 if (unreftors > 0) {
2442 print_unreftors (c);
2445 /* so we get possible bad argument warning */
2446 if (dispose_handler->line_no > 0)
2447 out_addline_infile (out, dispose_handler->line_no);
2448 out_printf (out, "\t___%x_%s_dispose(obj_self);\n",
2449 (guint)dispose_handler->unique_id, funcbase);
2450 if (dispose_handler->line_no > 0)
2451 out_addline_outfile (out);
2453 if (user_dispose_method != NULL) {
2454 if (user_dispose_method->line_no > 0)
2455 out_addline_infile (out, user_dispose_method->line_no);
2456 out_printf (out, "\t%s_dispose (self);\n", funcbase);
2457 if (user_dispose_method->line_no > 0)
2458 out_addline_outfile (out);
2461 if (unreftors > 0) {
2462 print_unreftors (c);
2466 "\tif (G_OBJECT_CLASS (parent_class)->dispose) \\\n"
2467 "\t\t(* G_OBJECT_CLASS (parent_class)->dispose) (obj_self);\n");
2470 out_printf(out, "}\n"
2471 "#undef __GOB_FUNCTION__\n\n");
2475 print_destructors (Class *c)
2478 for (li = ((Class *)class)->nodes;
2482 Variable *v = (Variable *)n;
2483 if (n->type == VARIABLE_NODE &&
2484 v->scope != CLASS_SCOPE &&
2485 ! v->destructor_unref)
2486 print_destructor (v);
2491 add_finalize (Class *c)
2495 "___finalize(GObject *obj_self)\n"
2498 "#define __GOB_FUNCTION__ \"%s::finalize\"\n",
2503 user_finalize_method != NULL) {
2504 const char *unused = "";
2506 unused = " G_GNUC_UNUSED";
2507 out_printf(out, "\t%s *self%s = %s (obj_self);\n",
2508 typebase, unused, macrobase);
2511 const char *unused = "";
2513 unused = " G_GNUC_UNUSED";
2514 out_printf(out, "\tgpointer priv%s = self->_priv;\n",
2518 if(finalize_handler) {
2519 if (destructors > 0) {
2520 print_destructors (c);
2523 /* so we get possible bad argument warning */
2524 if(finalize_handler->line_no > 0)
2525 out_addline_infile(out, finalize_handler->line_no);
2526 out_printf(out, "\t___%x_%s_finalize(obj_self);\n",
2527 (guint)finalize_handler->unique_id, funcbase);
2528 if(finalize_handler->line_no > 0)
2529 out_addline_outfile(out);
2531 if (user_finalize_method != NULL) {
2532 if (user_finalize_method->line_no > 0)
2533 out_addline_infile (out, user_finalize_method->line_no);
2534 out_printf (out, "\t%s_finalize (self);\n", funcbase);
2535 if (user_finalize_method->line_no > 0)
2536 out_addline_outfile (out);
2539 if (destructors > 0) {
2540 print_destructors (c);
2544 "\tif(G_OBJECT_CLASS(parent_class)->finalize) \\\n"
2545 "\t\t(* G_OBJECT_CLASS(parent_class)->finalize)(obj_self);\n");
2548 out_printf(out, "}\n"
2549 "#undef __GOB_FUNCTION__\n\n");
2553 make_bonobo_object_epv (Class *c, const char *classname)
2556 gboolean added_line = FALSE;
2558 for (li = c->nodes; li != NULL; li = li->next) {
2560 Method *m = (Method *)n;
2561 if(n->type != METHOD_NODE ||
2562 m->method == OVERRIDE_METHOD)
2565 if (m->bonobo_object_func) {
2566 if(m->line_no > 0) {
2567 out_addline_infile(out, m->line_no);
2569 } else if (m->line_no == 0 &&
2571 out_addline_outfile(out);
2574 out_printf (out, "\t%s->_epv.%s = self_%s;\n",
2575 classname, m->id, m->id);
2579 out_addline_outfile(out);
2582 static void add_class_private(Class *c, Method *m)
2584 const char *dynamic = c->dynamic ? "_DYNAMIC" : "";
2589 out_printf(out, "\n#if !defined(G_DEFINE%s_TYPE_EXTENDED)"
2590 " || !defined(G_ADD_PRIVATE%s)\n"
2591 "\tg_type_class_add_private(%s, sizeof(%sPrivate));\n"
2594 ((FuncArg *)m->args->data)->name, typebase);
2597 static void get_instance_private(Class *c, Method *m)
2599 const char *self = ((FuncArg *)m->args->data)->name;
2600 const char *dynamic = c->dynamic ? "_DYNAMIC" : "";
2603 if (always_private_struct) {
2604 out_printf(out, "\t%s->_priv = NULL;\n", self);
2610 out_printf(out, "\t%s->_priv = (%sPrivate *)\n"
2611 "#if defined(G_DEFINE%s_TYPE_EXTENDED)"
2612 " && defined(G_ADD_PRIVATE%s)\n"
2613 "\t\t%s_get_instance_private(%s);\n"
2615 "\t\tG_TYPE_INSTANCE_GET_PRIVATE\n"
2618 "\t\t\t, %sPrivate\n"
2624 self, macrotype, typebase);
2630 const char *unused = "";
2634 unused = " G_GNUC_UNUSED";
2636 for(li=c->nodes;li;li=g_list_next(li)) {
2640 if(n->type != METHOD_NODE)
2643 if(m->method == INIT_METHOD) {
2645 out_addline_infile(out, m->line_no);
2646 print_method(out, "static ", "\n", "", " ", "", "\n",
2647 m, FALSE, FALSE, FALSE, TRUE, TRUE,
2649 out_printf(out, "{\n");
2651 out_addline_outfile(out);
2653 "#define __GOB_FUNCTION__ \"%s::init\"\n",
2656 get_instance_private(c, m);
2658 if(initializers > 0) {
2660 for(li = ((Class *)class)->nodes;
2664 Variable *v = (Variable *)n;
2665 if(n->type != VARIABLE_NODE ||
2666 v->scope == CLASS_SCOPE)
2668 print_initializer(m, v);
2671 if(glade_widgets > 0) {
2673 for(li = ((Class *)class)->nodes;
2677 Variable *v = (Variable *)n;
2678 if(n->type != VARIABLE_NODE ||
2679 v->scope == CLASS_SCOPE)
2681 print_glade_widget(m, v);
2684 } else if(m->method == CLASS_INIT_METHOD) {
2685 gboolean did_base_obj = FALSE;
2688 out_addline_infile(out, m->line_no);
2689 print_method(out, "static ", "\n", "", " ", "", "\n",
2690 m, FALSE, FALSE, FALSE, TRUE, TRUE,
2692 out_printf(out, "{\n");
2694 out_addline_outfile(out);
2696 "#define __GOB_FUNCTION__ \"%s::class_init\"\n",
2698 if (set_properties > 0 ||
2699 get_properties > 0 ||
2706 "g_object_class%s = "
2707 "(GObjectClass*) %s;\n",
2709 ((FuncArg *)m->args->data)->name);
2710 did_base_obj = TRUE;
2715 ((FuncArg *)m->args->data)->name,
2718 add_class_private(c, m);
2720 if (initializers > 0) {
2722 for(li = ((Class *)class)->nodes;
2726 Variable *v = (Variable *)n;
2727 if(n->type == VARIABLE_NODE &&
2728 v->scope == CLASS_SCOPE)
2729 print_initializer(m, v);
2733 out_printf(out, "\n\tparent_class = ");
2735 out_printf(out, "(%sClass *)", ptypebase);
2736 out_printf(out, "g_type_class_ref (%s);\n",
2742 set_def_handlers(c, ((FuncArg *)m->args->data)->name);
2744 /* if there are no handlers for these things, we
2745 * need to set them up here */
2746 if(need_constructor)
2747 out_printf(out, "\tg_object_class->constructor "
2748 "= ___constructor;\n");
2749 if(need_dispose && !dispose_handler)
2750 out_printf(out, "\tg_object_class->dispose "
2752 if(need_finalize && !finalize_handler)
2753 out_printf(out, "\tg_object_class->finalize = "
2756 if(get_properties > 0 || set_properties > 0)
2759 if (c->bonobo_object_class != NULL) {
2760 make_bonobo_object_epv (c, ((FuncArg *)m->args->data)->name);
2766 out_printf(out, " {\n");
2767 out_addline_infile(out, m->ccode_line);
2768 out_printf(out, "%s\n", m->cbuf);
2769 out_addline_outfile(out);
2770 out_printf(out, " }\n");
2772 out_printf(out, "}\n"
2773 "#undef __GOB_FUNCTION__\n");
2778 add_argument (Argument *a, gboolean is_set)
2782 char *the_type_lower;
2787 line_no = a->set_line;
2790 line_no = a->get_line;
2794 s = g_strdup(a->name);
2796 out_printf(out, "\tcase PROP_%s:\n\t{", s);
2798 the_type_lower = g_strdup (a->gtktype);
2799 gob_strdown (the_type_lower);
2801 /* HACK because there is no g_value_set/get for unichar */
2802 if (strcmp (the_type_lower, "unichar") == 0) {
2803 g_free (the_type_lower);
2804 the_type_lower = g_strdup ("uint");
2809 const char *unused = "";
2811 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
2812 unused = " G_GNUC_UNUSED";
2815 if (a->atype != NULL &&
2816 /* gcc -Wbad-function-cast is wanking stupid, moronic
2817 and otherwise evil so we should just use a (gint)
2818 or (guint) cast, not the specific type cast */
2820 (strcmp (a->gtktype, "ENUM") != 0 &&
2821 strcmp (a->gtktype, "FLAGS") != 0)))
2822 cast = get_type (a->atype, TRUE);
2824 cast = g_strdup (get_cast (a->gtktype, FALSE));
2826 out_printf (out, "\t%s ARG%s = (%s) g_value_get_%s (VAL);\n",
2827 cast, unused, cast, the_type_lower);
2830 } else if ( ! is_set) {
2833 if (a->atype != NULL)
2834 cast = get_type (a->atype, TRUE);
2836 cast = g_strdup (get_cast (a->gtktype, FALSE));
2837 out_printf (out, "\t%s ARG;\n"
2838 "\tmemset (&ARG, 0, sizeof (%s));\n",
2844 out_printf(out, "\t\t{\n");
2846 out_addline_infile (out, line_no);
2847 out_printf (out, "%s\n", cbuf);
2849 out_addline_outfile (out);
2850 out_printf (out, "\t\t}\n");
2852 if (strcmp (a->gtktype, "OBJECT") == 0)
2853 out_printf (out, "\t\tg_value_set_%s (VAL, G_OBJECT (ARG));\n",
2856 out_printf (out, "\t\t"
2857 "g_value_set_%s (VAL, ARG);\n",
2860 g_free (the_type_lower);
2863 (no_gnu || for_cpp /* g++ has a cow with G_GNUC_UNUSED */)) {
2864 out_printf (out, "\t\tif (&ARG) break;\n");
2867 out_printf (out, "\t\tbreak;\n");
2869 out_printf (out, "\t}\n");
2873 add_property (Property *p, gboolean is_set)
2876 char *the_type_lower;
2882 line_no = p->set_line;
2885 line_no = p->get_line;
2890 name_upper = g_strdup (p->name);
2891 gob_strup (name_upper);
2892 the_type_lower = g_strdup (p->gtktype);
2893 gob_strdown (the_type_lower);
2895 out_printf (out, "\tcase PROP_%s:\n", name_upper);
2897 out_printf(out, "\t\t{\n");
2899 out_addline_infile (out, line_no);
2900 out_printf (out, "%s\n", cbuf);
2902 out_addline_outfile (out);
2903 out_printf (out, "\t\t}\n");
2905 g_free (name_upper);
2906 g_free (the_type_lower);
2908 out_printf (out, "\t\tbreak;\n");
2912 add_getset_arg(Class *c, gboolean is_set)
2915 const char *unused = "";
2916 const char *hack_unused = "";
2918 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
2919 unused = " G_GNUC_UNUSED";
2921 hack_unused = "if (&VAL || &pspec) break;\n\t\t";
2924 out_printf(out, "\nstatic void\n"
2925 "___object_%s_property (GObject *object,\n"
2926 "\tguint property_id,\n"
2927 "\t%sGValue *VAL%s,\n"
2928 "\tGParamSpec *pspec%s)\n"
2929 "#define __GOB_FUNCTION__ \"%s::%s_property\"\n"
2932 "\tself = %s (object);\n\n"
2933 "\tswitch (property_id) {\n",
2934 is_set ? "set" : "get",
2935 is_set ? "const " : "",
2939 is_set ? "set" : "get",
2944 for (li = c->nodes; li != NULL; li = li->next) {
2946 if (n->type == PROPERTY_NODE)
2947 add_property ((Property *)n, is_set);
2948 else if (n->type == ARGUMENT_NODE)
2949 add_argument ((Argument *)n, is_set);
2951 out_printf (out, "\tdefault:\n"
2952 "/* Apparently in g++ this is needed, glib is b0rk */\n"
2953 "#ifndef __PRETTY_FUNCTION__\n"
2954 "# undef G_STRLOC\n"
2955 "# define G_STRLOC __FILE__ \":\" G_STRINGIFY (__LINE__)\n"
2957 "\t\tG_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);\n"
2958 "\t\t%sbreak;\n\t}\n"
2960 "#undef __GOB_FUNCTION__\n", hack_unused);
2964 print_checks (Method *m, FuncArg *fa)
2968 gboolean checked_null = FALSE;
2969 is_void = (strcmp(m->mtype->name, "void")==0 &&
2970 m->mtype->pointer == NULL);
2972 for(li = fa->checks; li != NULL; li = li->next) {
2973 Check *ch = li->data;
2975 /* point to the method prot in .gob for failed checks */
2977 out_addline_infile(out, m->line_no);
2979 out_printf(out, "\tg_return_if_fail (");
2981 out_printf(out, "\tg_return_val_if_fail (");
2982 switch(ch->chtype) {
2984 out_printf(out, "%s != NULL", fa->name);
2985 checked_null = TRUE;
2988 s = make_pre_macro(fa->atype->name, "IS");
2990 out_printf(out, "%s (%s)", s, fa->name);
2992 /* if not check null, null may be valid */
2993 out_printf(out, "!(%s) || %s (%s)", fa->name,
2998 out_printf(out, "%s < %s", fa->name, ch->number);
3001 out_printf(out, "%s > %s", fa->name, ch->number);
3004 out_printf(out, "%s <= %s", fa->name, ch->number);
3007 out_printf(out, "%s >= %s", fa->name, ch->number);
3010 out_printf(out, "%s == %s", fa->name, ch->number);
3013 out_printf(out, "%s != %s", fa->name, ch->number);
3017 out_printf(out, ");\n");
3019 out_printf(out, ", (");
3020 print_type(out, m->mtype, TRUE);
3021 out_printf(out, ")%s);\n",
3022 m->onerror?m->onerror:"0");
3028 print_preconditions(Method *m)
3032 for(li=m->args;li;li=g_list_next(li)) {
3033 FuncArg *fa = li->data;
3035 print_checks(m, fa);
3038 out_addline_outfile(out);
3042 print_method_body (Method *m, gboolean pre, gboolean unused_self)
3044 out_printf(out, "{\n");
3046 out_addline_outfile(out);
3047 out_printf(out, "#define __GOB_FUNCTION__ \"%s::%s\"\n",
3048 ((Class *)class)->otype,
3051 print_preconditions(m);
3055 (no_gnu || for_cpp) &&
3057 ((FuncArg *)(m->args->data))->name != NULL &&
3058 strcmp (((FuncArg *)(m->args->data))->name, "self") == 0) {
3059 out_printf (out, "\tif (&self) { ; }\n");
3062 /* Note: the trailing }'s are on one line, this is so
3063 that we get the no return warning correctly and point to
3064 the correct line in the .gob file, yes this is slightly
3065 ugly in the .c file, but that is not supposed to be
3066 human readable anyway. */
3068 out_printf(out, "{\n");
3070 out_addline_infile(out, m->ccode_line);
3071 out_printf(out, "\t%s}", m->cbuf);
3074 /* Note, there is no \n between the last } and this } so that
3075 * errors/warnings reported on the end of the body get pointed to the
3076 * right line in the .gob source */
3077 out_printf(out, "}\n");
3080 out_addline_outfile(out);
3081 out_printf(out, "#undef __GOB_FUNCTION__\n");
3085 put_signal_args (Method *m)
3091 if (m->args->next == NULL)
3094 for (ali = m->gtktypes->next, li = m->args->next, i = 1;
3095 li != NULL && ali != NULL;
3096 li = li->next, ali = ali->next, i++) {
3097 FuncArg *fa = li->data;
3098 char *str = ali->data;
3099 char *cast = g_strdup (get_cast (str, FALSE));
3100 /* FIXME: This code is so fucking ugly it hurts */
3101 gboolean do_static =
3102 (strcmp (str, "STRING") == 0 ||
3103 strcmp (str, "BOXED") == 0 ||
3104 strncmp (str, "BOXED_", 6) == 0);
3109 cast = get_type (fa->atype, TRUE);
3111 /* we should have already proved before that
3112 the we know all the types */
3113 g_assert (cast != NULL);
3115 if (strncmp (str, "BOXED_", 6) == 0)
3116 t = g_strdup (&(str[6]));
3118 t = g_strconcat ("G_TYPE_", str, NULL);
3121 "\t___param_values[%d].g_type = 0;\n"
3122 "\tg_value_init (&___param_values[%d], %s);\n",
3126 if (strcmp (str, "UNICHAR") == 0)
3127 /* hack because glib is braindamaged */
3128 set_func = g_strdup ("g_value_set_uint");
3129 else if (strncmp (str, "BOXED_", 6) == 0)
3130 set_func = g_strdup ("g_value_set_static_boxed");
3132 set_func = g_strdup_printf ("g_value_set%s_%s",
3133 do_static ? "_static" : "",
3135 gob_strdown (set_func);
3137 out_printf (out, "\t%s (&___param_values[%d], (%s) %s);\n\n",
3138 set_func, i, cast, fa->name);
3146 clear_signal_args (Method *m)
3151 out_printf (out, "\n\tg_value_unset (&___param_values[0]);\n");
3153 if (m->args->next == NULL)
3156 for (li = m->args->next, i = 1;
3158 li = li->next, i++) {
3160 "\tg_value_unset (&___param_values[%d]);\n", i);
3165 get_arg_names_for_macro (Method *m)
3170 GString *gs = g_string_new(NULL);
3172 for(li=m->args;li;li=g_list_next(li)) {
3173 FuncArg *arg = li->data;
3174 g_string_append_printf(gs, "%s___%s", sep, arg->name);
3179 g_string_free(gs, FALSE);
3183 static gboolean method_is_void(Method *m)
3185 return !strcmp(m->mtype->name, "void") && !m->mtype->pointer;
3188 static const char *method_err_retval(Method *m)
3190 if (method_is_void(m))
3198 put_interface_parent_handler(Method *m)
3200 const char *errval = method_err_retval(m);
3201 char *name = replace_sep(m->interface, '_');
3202 char *args = get_arg_names_for_macro(m);
3204 out_printf(out, "#define PARENT_HANDLER(%s) (%s_parent_iface \\\n"
3205 "\t? %s_parent_iface->%s(%s) \\\n"
3206 "\t: %s)\n", args, name, name, m->id, args, errval);
3213 put_method(Method *m)
3215 char *s, *args, *doc;
3217 is_void = (strcmp(m->mtype->name, "void")==0 &&
3218 m->mtype->pointer == NULL);
3219 out_printf(out, "\n");
3220 if(m->method != OVERRIDE_METHOD) {
3221 doc = get_gtk_doc(m->id);
3223 out_printf(out, "%s", doc);
3229 case REGULAR_METHOD:
3231 out_addline_infile(out, m->line_no);
3232 if(m->scope == PRIVATE_SCOPE)
3233 print_method(out, "static ", "\n", "", " ", "", "\n",
3234 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3235 else /* PUBLIC, PROTECTED */
3236 print_method(out, "", "\n", "", " ", "", "\n",
3237 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3240 out_addline_outfile(out);
3241 put_interface_parent_handler(m);
3244 print_method_body(m, TRUE, TRUE);
3247 out_printf(out, "#undef PARENT_HANDLER\n");
3250 /* the outfile line was added above */
3252 case SIGNAL_FIRST_METHOD:
3253 case SIGNAL_LAST_METHOD:
3255 out_addline_infile(out, m->line_no);
3256 if(m->scope == PRIVATE_SCOPE)
3257 print_method(out, "static ", "\n", "", " ", "", "\n",
3258 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3259 else /* PUBLIC, PROTECTED */
3260 print_method(out, "", "\n", "", " ", "", "\n",
3261 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3262 out_printf (out, "{\n");
3264 out_addline_outfile (out);
3267 "\tGValue ___param_values[%d];\n"
3268 "\tGValue ___return_val;\n\n"
3269 "memset (&___return_val, 0, "
3270 "sizeof (___return_val));\n"
3271 "memset (&___param_values, 0, "
3272 "sizeof (___param_values));\n\n",
3273 g_list_length (m->args));
3275 print_preconditions (m);
3278 "\n\t___param_values[0].g_type = 0;\n"
3279 "\tg_value_init (&___param_values[0], G_TYPE_FROM_INSTANCE (%s));\n"
3280 "\tg_value_set_instance (&___param_values[0], (gpointer) %s);\n\n",
3281 ((FuncArg *)m->args->data)->name,
3282 ((FuncArg *)m->args->data)->name);
3284 put_signal_args (m);
3286 if (strcmp (m->gtktypes->data, "NONE") != 0) {
3287 const char *defret = NULL;
3289 out_printf (out, "\tg_value_init (&___return_val, G_TYPE_%s);\n",
3290 (char *)m->gtktypes->data);
3292 if (m->defreturn != NULL)
3293 defret = m->defreturn;
3294 else if (m->onerror != NULL)
3295 defret = m->onerror;
3297 if (defret != NULL) {
3299 /* FIXME: This code is so fucking ugly it hurts */
3300 gboolean do_static =
3301 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
3302 strcmp ((char *)m->gtktypes->data, "BOXED") == 0);
3303 char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
3305 cast = get_type (m->mtype, TRUE);
3307 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
3308 /* hack because glib is braindamaged */
3309 set_func = g_strdup ("g_value_set_uint");
3311 set_func = g_strdup_printf ("g_value_set%s_%s",
3312 do_static ? "_static" : "",
3313 (char *)m->gtktypes->data);
3314 gob_strdown (set_func);
3316 out_printf (out, "\t%s (&___return_val, (%s) (%s));\n",
3317 set_func, cast, defret);
3322 out_printf (out, "\n");
3325 s = g_strdup (m->id);
3328 out_printf(out, "\tg_signal_emitv (___param_values,\n"
3329 "\t\tobject_signals[%s_SIGNAL],\n"
3330 "\t\t0 /* detail */,\n"
3331 "\t\t&___return_val);\n", s);
3335 clear_signal_args (m);
3337 if (strcmp (m->gtktypes->data, "NONE") != 0) {
3338 char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
3340 /* Hack because glib is very very braindead */
3342 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
3343 strcmp ((char *)m->gtktypes->data, "BOXED") == 0 ||
3344 strcmp ((char *)m->gtktypes->data, "OBJECT") == 0 ||
3345 strcmp ((char *)m->gtktypes->data, "PARAM") == 0);
3347 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
3348 /* hack because glib is braindamaged */
3349 getfunc = g_strdup ("g_value_get_uint");
3351 getfunc = g_strdup_printf ("g_value_%s_%s",
3352 do_dup ? "dup" : "get",
3353 (char *)m->gtktypes->data);
3354 gob_strdown (getfunc);
3357 cast = get_type (m->mtype, TRUE);
3362 print_type (out, m->mtype, TRUE);
3364 " ___ret = (%s) %s (&___return_val);\n"
3365 "\t\tg_value_unset (&___return_val);\n"
3366 "\t\treturn ___ret;\n"
3373 out_printf(out, "}\n");
3378 out_addline_infile(out, m->line_no);
3379 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
3380 m, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE);
3381 print_method_body(m, FALSE, TRUE);
3382 /* the outfile line was added above */
3384 case VIRTUAL_METHOD:
3386 out_addline_infile(out, m->line_no);
3387 if(m->scope==PRIVATE_SCOPE)
3388 print_method(out, "static ", "\n", "", " ", "", "\n",
3389 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3390 else /* PUBLIC, PROTECTED */
3391 print_method(out, "", "\n", "", " ", "", "\n",
3392 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3393 out_printf(out, "{\n");
3394 out_addline_outfile(out);
3395 out_printf(out, "\t%sClass *klass;\n", typebase);
3396 print_preconditions(m);
3397 out_printf(out, "\tklass = %s_GET_CLASS(%s);\n\n"
3398 "\tif(klass->%s)\n",
3399 macrobase, ((FuncArg *)m->args->data)->name,
3401 if(strcmp(m->mtype->name, "void") == 0 &&
3402 m->mtype->pointer == NULL) {
3404 out_printf(out, "\t\t(*klass->%s)(%s",
3406 ((FuncArg *)m->args->data)->name);
3407 for(li=m->args->next;li;li=g_list_next(li)) {
3408 FuncArg *fa = li->data;
3409 out_printf(out, ",%s", fa->name);
3411 out_printf(out, ");\n}\n");
3414 out_printf(out, "\t\treturn (*klass->%s)(%s",
3416 ((FuncArg *)m->args->data)->name);
3417 for(li=m->args->next;li;li=g_list_next(li)) {
3418 FuncArg *fa = li->data;
3419 out_printf(out, ",%s", fa->name);
3421 out_printf(out, ");\n"
3424 print_type(out, m->mtype, TRUE);
3426 out_printf(out, ")(%s);\n}\n", m->defreturn);
3428 out_printf(out, ")(%s);\n}\n", m->onerror);
3430 out_printf(out, ")(0);\n}\n");
3436 out_addline_infile(out, m->line_no);
3437 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
3438 m, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE);
3439 print_method_body(m, FALSE, TRUE);
3440 /* the outfile line was added above */
3442 case OVERRIDE_METHOD:
3446 out_addline_infile(out, m->line_no);
3447 s = g_strdup_printf("\n___%x_", (guint)m->unique_id);
3448 print_method(out, "static ", s, "", " ", "", "\n",
3449 m, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE);
3451 out_addline_outfile(out);
3452 s = replace_sep(m->otype, '_');
3454 args = get_arg_names_for_macro(m);
3456 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
3457 "\t{ if(%s_CLASS(parent_class)->%s) \\\n"
3458 "\t\t(* %s_CLASS(parent_class)->%s)(%s); }\n",
3459 args, s, m->id, s, m->id, args);
3461 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
3462 "\t((%s_CLASS(parent_class)->%s)? \\\n"
3463 "\t\t(* %s_CLASS(parent_class)->%s)(%s): \\\n"
3465 args, s, m->id, s, m->id, args);
3466 out_printf(out, "(");
3467 print_type(out, m->mtype, TRUE);
3468 out_printf(out, ")%s))\n",
3469 m->onerror?m->onerror:"0");
3473 print_method_body(m, TRUE, TRUE);
3474 /* the outfile line was added above */
3475 out_printf(out, "#undef PARENT_HANDLER\n");
3477 case CONSTRUCTOR_METHOD:
3478 case DISPOSE_METHOD:
3479 case FINALIZE_METHOD:
3481 out_addline_infile(out, m->line_no);
3482 print_method(out, "static ", "\n", "", " ", "", "\n",
3483 m, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE);
3484 print_method_body(m, TRUE, TRUE);
3485 /* the outfile line was added above */
3494 char *outfile, *outfileh, *outfileph;
3496 outfilebase = g_strconcat (fullfilebase, for_cpp ? ".cc" : ".c", NULL);
3497 outfile = g_strconcat(outfilebase, no_touch ? "#gob#" : "", NULL);
3499 outfilehbase = g_strconcat (fullfilebase, ".h", NULL);
3500 outfileh = g_strconcat(outfilehbase, no_touch_headers ? "#gob#" : "", NULL);
3502 if ((privates > 0 || protecteds > 0 ||
3503 private_header == PRIVATE_HEADER_ALWAYS) &&
3504 private_header != PRIVATE_HEADER_NEVER) {
3505 char sep[2] = {0,0};
3508 outfilephbase = g_strconcat (fullfilebase, sep, "private.h", NULL);
3509 outfileph = g_strconcat (outfilephbase, no_touch_headers ? "#gob#" : "", NULL);
3511 outfilephbase = NULL;
3517 out = fopen (outfile, "w");
3519 error_printf (GOB_ERROR, 0,
3520 "Cannot open outfile: %s", outfile);
3522 outh = fopen (outfileh, "w");
3524 error_printf (GOB_ERROR, 0,
3525 "Cannot open outfile: %s", outfileh);
3527 if (outfileph != NULL) {
3528 outph = fopen (outfileph, "w");
3529 if (outph == NULL) {
3530 error_printf (GOB_ERROR, 0,
3531 "Cannot open outfile: %s",
3539 put_argument_nongnu_wrappers (Class *c)
3543 if (get_properties < 0 && set_properties < 0)
3546 for (li = c->nodes; li != NULL; li = li->next) {
3548 const char *name, *gtktype;
3554 if (n->type == ARGUMENT_NODE) {
3555 Argument *a = (Argument *)n;
3557 gtktype = a->gtktype;
3559 get = a->get != NULL;
3560 set = a->set != NULL;
3561 } else if (n->type == PROPERTY_NODE) {
3562 Property *p = (Property *)n;
3564 gtktype = p->gtktype;
3566 get = p->get != NULL;
3567 set = p->set != NULL;
3572 aname = g_strdup (name);
3576 cast = get_type (atype, TRUE);
3578 cast = g_strdup (get_cast (gtktype, TRUE));
3582 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3583 "\"%s\",(%s)(arg)\n",
3584 macrobase, aname, name, cast);
3586 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3587 "\"%s\",(%s*)(arg)\n",
3588 macrobase, aname, name, cast);
3591 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3593 macrobase, aname, name);
3595 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3597 macrobase, aname, name);
3605 put_argument_gnu_wrappers(Class *c)
3609 if(get_properties < 0 && set_properties < 0)
3612 for (li = c->nodes; li != NULL; li = li->next) {
3614 const char *name, *gtktype;
3620 if (n->type == ARGUMENT_NODE) {
3621 Argument *a = (Argument *)n;
3623 gtktype = a->gtktype;
3625 get = a->get != NULL;
3626 set = a->set != NULL;
3627 } else if (n->type == PROPERTY_NODE) {
3628 Property *p = (Property *)n;
3630 gtktype = p->gtktype;
3632 get = p->get != NULL;
3633 set = p->set != NULL;
3638 aname = g_strdup (name);
3642 cast = get_type (atype, TRUE);
3644 cast = g_strdup (get_cast (gtktype, TRUE));
3648 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3649 "\"%s\", __extension__ ({%sz = (arg); z;})\n",
3650 macrobase, aname, name, cast);
3652 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3653 "\"%s\", __extension__ ({%s*z = (arg); z;})\n",
3654 macrobase, aname, name, cast);
3657 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3659 macrobase, aname, name);
3661 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3663 macrobase, aname, name);
3671 print_ccode_block(CCode *cc)
3674 switch(cc->cctype) {
3676 /* HT code is printed exactly like normal header
3677 code but is printed before */
3680 out_printf(fp, "\n");
3683 /* AT code is printed exactly like normal 'all'
3684 code but is printed before */
3687 out_printf(outph, "\n");
3688 out_printf(outph, "%s\n", cc->cbuf);
3689 out_addline_infile(outph, cc->line_no);
3690 out_addline_outfile(outph);
3692 out_printf(outh, "\n");
3693 out_printf(outh, "%s\n", cc->cbuf);
3695 out_printf(fp, "\n");
3696 out_addline_infile(fp, cc->line_no);
3702 out_printf(fp, "\n");
3703 out_addline_infile(fp, cc->line_no);
3710 out_printf(fp, "\n");
3711 out_addline_infile(fp, cc->line_no);
3714 out_printf(fp, "%s\n", cc->cbuf);
3715 if(cc->cctype == C_CCODE ||
3716 cc->cctype == AD_CCODE ||
3717 cc->cctype == A_CCODE ||
3718 cc->cctype == AT_CCODE ||
3719 cc->cctype == PH_CCODE)
3720 out_addline_outfile(fp);
3724 print_class_block(Class *c)
3728 gboolean printed_private = FALSE;
3732 out_printf(outph ? outph : outh, "#include <gtk/gtk.h>\n");
3733 out_printf(outph ? outph : outh, "#include <glade/glade-xml.h>\n\n");
3737 out_printf(out, "/* utility types we may need */\n");
3738 if(special_array[SPECIAL_2POINTER])
3739 out_printf(out, "typedef struct { "
3740 "gpointer a; gpointer b; "
3741 "} ___twopointertype;\n");
3742 if(special_array[SPECIAL_3POINTER])
3743 out_printf(out, "typedef struct { "
3744 "gpointer a; gpointer b; "
3746 "} ___threepointertype;\n");
3747 if(special_array[SPECIAL_INT_POINTER])
3748 out_printf(out, "typedef struct { "
3749 "gint a; gpointer b; "
3750 "} ___intpointertype;\n");
3751 out_printf(out, "\n");
3754 out_printf(outh, "\n/*\n"
3755 " * Type checking and casting macros\n"
3757 out_printf(outh, "#define %s\t"
3758 "(%s_get_type())\n",
3759 macrotype, funcbase);
3760 out_printf(outh, "#define %s(obj)\t"
3761 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s)\n",
3762 macrobase, funcbase, typebase);
3763 out_printf(outh, "#define %s_CONST(obj)\t"
3764 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s const)\n",
3765 macrobase, funcbase, typebase);
3766 out_printf(outh, "#define %s_CLASS(klass)\t"
3767 "G_TYPE_CHECK_CLASS_CAST((klass), %s_get_type(), %sClass)\n",
3768 macrobase, funcbase, typebase);
3769 out_printf(outh, "#define %s(obj)\t"
3770 "G_TYPE_CHECK_INSTANCE_TYPE((obj), %s_get_type ())\n\n",
3773 "#define %s_GET_CLASS(obj)\t"
3774 "G_TYPE_INSTANCE_GET_CLASS((obj), %s_get_type(), %sClass)\n",
3775 macrobase, funcbase, typebase);
3777 if ( ! no_self_alias) {
3778 out_printf(out, "/* self casting macros */\n");
3779 out_printf(out, "#define SELF(x) %s(x)\n", macrobase);
3780 out_printf(out, "#define SELF_CONST(x) %s_CONST(x)\n", macrobase);
3781 out_printf(out, "#define IS_SELF(x) %s(x)\n", macrois);
3782 out_printf(out, "#define TYPE_SELF %s\n", macrotype);
3783 out_printf(out, "#define SELF_CLASS(x) %s_CLASS(x)\n\n",
3785 out_printf(out, "#define SELF_GET_CLASS(x) %s_GET_CLASS(x)\n\n",
3788 out_printf(out, "/* self typedefs */\n");
3789 out_printf(out, "typedef %s Self;\n", typebase);
3790 out_printf(out, "typedef %sClass SelfClass;\n\n", typebase);
3794 always_private_struct) {
3795 out_printf (outh, "\n/* Private structure type */\n");
3796 out_printf (outh, "typedef struct _%sPrivate %sPrivate;\n",
3797 typebase, typebase);
3799 out_printf (outh, "/* There are no privates, this "
3800 "structure is thus never defined */\n");
3803 out_printf (outh, "\n/*\n"
3804 " * Main object structure\n"
3806 s = replace_sep (c->otype, '_');
3808 out_printf (outh, "#ifndef __TYPEDEF_%s__\n"
3809 "#define __TYPEDEF_%s__\n", s, s);
3811 out_printf (outh, "typedef struct _%s %s;\n"
3812 "#endif\n", typebase, typebase);
3813 out_printf (outh, "struct _%s {\n\t%s __parent__;\n",
3814 typebase, ptypebase);
3815 for (li = c->nodes; li; li=li->next) {
3816 static gboolean printed_public = FALSE;
3818 Variable *v = (Variable *)n;
3819 if(n->type == VARIABLE_NODE &&
3820 v->scope == PUBLIC_SCOPE) {
3821 if( ! printed_public) {
3822 out_printf(outh, "\t/*< public >*/\n");
3823 printed_public = TRUE;
3825 put_variable((Variable *)n, outh);
3828 /* put protecteds always AFTER publics */
3829 for (li = c->nodes; li != NULL; li = li->next) {
3831 Variable *v = (Variable *)n;
3832 if (n->type == VARIABLE_NODE &&
3833 v->scope == PROTECTED_SCOPE) {
3834 if ( ! printed_private) {
3835 out_printf (outh, "\t/*< private >*/\n");
3836 printed_private = TRUE;
3838 put_variable ((Variable *)n, outh);
3842 always_private_struct) {
3843 if ( ! printed_private)
3844 out_printf (outh, "\t/*< private >*/\n");
3845 out_printf (outh, "\t%sPrivate *_priv;\n", typebase);
3847 out_printf (outh, "};\n");
3852 /* if we are to stick this into the private
3853 header, if not stick it directly into the
3860 out_printf (outfp, "struct _%sPrivate {\n",
3864 for(li=c->nodes; li; li=li->next) {
3866 Variable *v = (Variable *)n;
3867 if(n->type == VARIABLE_NODE &&
3868 v->scope == PRIVATE_SCOPE) {
3869 out_addline_infile(outfp, v->line_no);
3870 put_variable(v, outfp);
3873 out_addline_outfile(outfp);
3875 out_printf(outfp, "};\n");
3878 out_printf(outh, "\n/*\n"
3879 " * Class definition\n"
3881 out_printf(outh, "typedef struct _%sClass %sClass;\n",
3882 typebase, typebase);
3884 "struct _%sClass {\n\t%sClass __parent__;\n",
3885 typebase, ptypebase);
3886 for(li = c->nodes; li != NULL; li = li->next) {
3888 if(n->type == METHOD_NODE)
3889 put_vs_method((Method *)n);
3891 /* If BonoboX type class put down the epv */
3892 if (c->bonobo_object_class != NULL) {
3894 "\t/* Bonobo object epv */\n"
3895 "\tPOA_%s__epv _epv;\n",
3896 c->bonobo_object_class);
3898 /* put class scope variables */
3899 for (li = c->nodes; li != NULL; li = li->next) {
3901 Variable *v = (Variable *)n;
3902 if (n->type == VARIABLE_NODE &&
3903 v->scope == CLASS_SCOPE)
3904 put_variable ((Variable *)n, outh);
3906 out_printf (outh, "};\n\n");
3908 out_printf (out, "/* here are local prototypes */\n");
3909 if (set_properties > 0) {
3910 out_printf (out, "static void ___object_set_property "
3911 "(GObject *object, guint property_id, "
3912 "const GValue *value, GParamSpec *pspec);\n");
3914 if (get_properties > 0) {
3915 out_printf (out, "static void ___object_get_property "
3916 "(GObject *object, guint property_id, "
3917 "GValue *value, GParamSpec *pspec);\n");
3920 out_printf (outh, "\n/*\n"
3921 " * Public methods\n"
3924 if (!overrode_get_type && !no_gnu) {
3926 * For ordinary "static" types it should be safe to mark the
3927 * get_type implementation as const, since the get_type
3928 * function return really is constant at the call boundary
3929 * (even though there is an initial setup on the first call).
3930 * But for dynamic types, since the registration is explicitly
3931 * separated, we need to settle for "pure" as the results of
3932 * get_type differ before and after type registration.
3934 out_printf(outh, "GType\t%s_get_type\t(void) %s;\n", funcbase,
3935 c->dynamic ? "G_GNUC_PURE" : "G_GNUC_CONST");
3939 out_printf(outh, "void\t%s_register_type\t(GTypeModule *);\n",
3943 for(li = c->nodes; li != NULL; li = li->next) {
3945 if(n->type == METHOD_NODE) {
3946 put_pub_method((Method *)n);
3947 put_prot_method((Method *)n);
3948 put_priv_method_prot((Method *)n);
3952 /* this idea is less and less apealing to me */
3954 out_printf (outh, "\n/*\n"
3955 " * Signal connection wrapper macros\n"
3958 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3959 put_signal_macros (c, TRUE);
3960 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3961 put_signal_macros (c, FALSE);
3962 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n");
3964 put_signal_macros (c, FALSE);
3965 out_printf(outh, "\n");
3968 out_printf (out, "\n/*\n"
3969 " * Signal connection wrapper macro shortcuts\n"
3971 put_local_signal_macros (c);
3972 out_printf(outh, "\n");
3975 /* argument wrapping macros */
3976 if(get_properties > 0 || set_properties > 0) {
3977 out_printf(outh, "\n/*\n"
3978 " * Argument wrapping macros\n"
3981 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3982 put_argument_gnu_wrappers(c);
3983 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3984 put_argument_nongnu_wrappers(c);
3985 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n");
3987 put_argument_nongnu_wrappers(c);
3992 for(li = c->nodes; li != NULL; li = li->next) {
3994 if(n->type == METHOD_NODE)
3995 add_signal_prots((Method *)n);
4001 if(any_method_to_alias(c)) {
4002 out_printf (out, "/* Short form macros */\n");
4003 make_method_aliases (c);
4006 add_interface_inits (c);
4008 if (!overrode_get_type) {
4009 if (c->bonobo_object_class != NULL)
4010 add_bonobo_object_get_type();
4011 else if (c->dynamic)
4012 add_dynamic_get_type();
4017 out_printf (out, "/* a macro for creating a new object of our type */\n");
4019 "#define GET_NEW ((%s *)g_object_new(%s_get_type(), NULL))\n\n",
4020 typebase, funcbase);
4022 out_printf (out, "/* a function for creating a new object of our type */\n");
4023 out_printf (out, "#include <stdarg.h>\n");
4025 "static %s * GET_NEW_VARG (const char *first, ...)%s;\n"
4026 "static %s *\nGET_NEW_VARG (const char *first, ...)\n"
4027 "{\n\t%s *ret;\n\tva_list ap;\n"
4028 "\tva_start (ap, first);\n"
4029 "\tret = (%s *)g_object_new_valist (%s_get_type (), "
4032 "\treturn ret;\n}\n\n",
4034 no_gnu ? "" : " G_GNUC_UNUSED",
4035 typebase, typebase, typebase, funcbase);
4039 out_printf (out, "/* a function to connect glade callback */\n");
4040 out_printf (out,"static void\n"
4041 "___glade_xml_connect_foreach(const gchar *handler_name,\n"
4042 "GObject *object,\n"
4043 "const gchar *signal_name,\n"
4044 "const gchar *signal_data,\n"
4045 "GObject *connect_object,\n"
4047 "gpointer user_data)\n"
4049 "\tstatic GModule * allsymbols = NULL;\n"
4051 "\tif (!allsymbols) allsymbols = g_module_open(NULL, 0);\n"
4052 "\tif (allsymbols) {\n"
4053 "\t\tgchar * func_name = g_strdup_printf(\"%s_%%s\", handler_name);\n"
4054 "\t\tGCallback func;\n"
4056 "\t\tif (!g_module_symbol(allsymbols, func_name, (gpointer)&func)){\n"
4057 "\t\t\tif (!g_module_symbol(allsymbols, handler_name, (gpointer)&func)) {\n"
4058 "\t\t\t\tg_warning(\"could not find signal handler '%%s'.\", func_name);\n"
4059 "\t\t\t\tg_free(func_name);\n"
4064 "\t\t\tg_signal_connect_data(object, signal_name, func, user_data, NULL, G_CONNECT_AFTER | G_CONNECT_SWAPPED);\n"
4066 "\t\t\tg_signal_connect_data(object, signal_name, func, user_data, NULL, G_CONNECT_SWAPPED);\n"
4067 "\t\tg_free(func_name);\n"
4074 for (li = nodes; li != NULL; li = li->next) {
4075 Node *node = li->data;
4076 if (node->type == CCODE_NODE) {
4077 CCode *cc = (CCode *)node;
4078 if (cc->cctype == AD_CCODE)
4079 print_ccode_block (cc);
4083 if (need_constructor)
4084 add_constructor (c);
4094 if(set_properties > 0) {
4095 add_getset_arg(c, TRUE);
4098 if(get_properties > 0) {
4099 add_getset_arg(c, FALSE);
4102 for(li = c->nodes; li != NULL; li = li->next) {
4104 if(n->type == METHOD_NODE)
4105 put_method((Method *)n);
4108 add_bad_hack_to_avoid_unused_warnings(c);
4112 print_useful_macros(void)
4114 int major = 0, minor = 0, pl = 0;
4117 sscanf (VERSION, "%d.%d.%d", &major, &minor, &pl);
4118 out_printf (out, "#define GOB_VERSION_MAJOR %d\n", major);
4119 out_printf (out, "#define GOB_VERSION_MINOR %d\n", minor);
4120 out_printf (out, "#define GOB_VERSION_PATCHLEVEL %d\n\n", pl);
4122 /* Useful priv macro thingie */
4123 /* FIXME: this should be done the same way that priv is, as a var,
4125 out_printf (out, "#define selfp (self->_priv)\n\n");
4129 print_more_useful_macros (void)
4132 out_printf (out, "#define ___GOB_LIKELY(expr) (expr)\n");
4133 out_printf (out, "#define ___GOB_UNLIKELY(expr) (expr)\n");
4135 out_printf (out, "#ifdef G_LIKELY\n");
4136 out_printf (out, "#define ___GOB_LIKELY(expr) G_LIKELY(expr)\n");
4137 out_printf (out, "#define ___GOB_UNLIKELY(expr) G_UNLIKELY(expr)\n");
4138 out_printf (out, "#else /* ! G_LIKELY */\n");
4139 out_printf (out, "#define ___GOB_LIKELY(expr) (expr)\n");
4140 out_printf (out, "#define ___GOB_UNLIKELY(expr) (expr)\n");
4141 out_printf (out, "#endif /* G_LIKELY */\n");
4146 print_file_comments(void)
4148 out_printf(outh, "/* Generated by GOB (v%s)"
4149 " (do not edit directly) */\n\n", VERSION);
4151 out_printf(outph, "/* Generated by GOB (v%s)"
4152 " (do not edit directly) */\n\n", VERSION);
4153 out_printf(out, "/* Generated by GOB (v%s)"
4154 " (do not edit directly) */\n\n", VERSION);
4156 out_printf(out, "/* End world hunger, donate to the World Food Programme, http://www.wfp.org */\n\n");
4160 print_includes(void)
4162 gboolean found_header;
4165 /* We may need string.h for memset */
4166 if ( ! g_list_find_custom(include_files, "string.h", (GCompareFunc)strcmp)) {
4167 out_printf(out, "#include <string.h> /* memset() */\n\n");
4170 p = g_strconcat(filebase, ".h", NULL);
4171 found_header = TRUE;
4172 if( ! g_list_find_custom(include_files, p, (GCompareFunc)strcmp)) {
4173 out_printf(out, "#include \"%s.h\"\n\n", filebase);
4174 found_header = FALSE;
4178 /* if we are creating a private header see if it was included */
4180 char sep[2] = {0,0};
4183 p = g_strconcat(filebase, sep, "private.h", NULL);
4184 if( ! g_list_find_custom(include_files, p,
4185 (GCompareFunc)strcmp)) {
4186 out_printf(out, "#include \"%s%sprivate.h\"\n\n",
4190 error_printf(GOB_WARN, 0,
4191 "Implicit private header include "
4193 "\tsource file, while public "
4194 "header is at a custom location, "
4196 "\texplicitly include "
4197 "the private header below the "
4205 print_header_prefixes(void)
4209 p = replace_sep(((Class *)class)->otype, '_');
4211 out_printf(outh, "#ifndef __%s_H__\n#define __%s_H__\n\n", p, p);
4213 out_printf(outph, "#ifndef __%s_PRIVATE_H__\n"
4214 "#define __%s_PRIVATE_H__\n\n"
4215 "#include \"%s.h\"\n\n", p, p, filebase);
4218 if( ! no_extern_c) {
4219 out_printf(outh, "#ifdef __cplusplus\n"
4221 "#endif /* __cplusplus */\n\n");
4223 out_printf(outph, "#ifdef __cplusplus\n"
4225 "#endif /* __cplusplus */\n\n");
4230 print_header_postfixes(void)
4233 out_printf(outh, "\n#ifdef __cplusplus\n"
4235 "#endif /* __cplusplus */\n");
4236 out_printf(outh, "\n#endif\n");
4239 out_printf(outph, "\n#ifdef __cplusplus\n"
4241 "#endif /* __cplusplus */\n");
4242 out_printf(outph, "\n#endif\n");
4251 /* print the AT_CCODE and CT_CCODE blocks */
4252 for(li = nodes; li != NULL; li = li->next) {
4253 Node *node = li->data;
4254 if(node->type == CCODE_NODE) {
4255 CCode *cc = (CCode *)node;
4256 if (cc->cctype == AT_CCODE ||
4257 cc->cctype == CT_CCODE)
4258 print_ccode_block((CCode *)node);
4264 print_header_top(void)
4268 /* mandatory includes */
4269 out_printf (outh, "#include <glib.h>\n");
4270 out_printf (outh, "#include <glib-object.h>\n");
4272 /* print the HT_CCODE blocks */
4273 for (li = nodes; li != NULL; li = li->next) {
4274 Node *node = li->data;
4275 if (node->type == CCODE_NODE) {
4276 CCode *cc = (CCode *)node;
4277 if (cc->cctype == HT_CCODE)
4278 print_ccode_block ((CCode *)node);
4284 print_enum (EnumDef *enode)
4291 funcprefix = replace_sep (enode->etype, '_');
4292 gob_strdown (funcprefix);
4293 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
4295 type = remove_sep (enode->etype);
4297 out_printf (outh, "\ntypedef enum {\n");
4299 for (li = enode->values; li != NULL; li = li->next) {
4300 EnumValue *value = li->data;
4302 char *sname = gob_strdown (g_strdup (value->name));
4304 while ((p = strchr (sname, '_')) != NULL)
4307 out_printf (outh, "\t%s_%s", enode->prefix, value->name);
4308 if (value->value != NULL)
4309 out_printf (outh, " = %s", value->value);
4310 if (li->next != NULL)
4311 out_printf (outh, ",\n");
4313 out_printf (outh, "\n");
4315 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
4316 enode->prefix, value->name,
4317 enode->prefix, value->name,
4323 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
4325 out_printf (outh, "} %s;\n", type);
4327 str = make_pre_macro (enode->etype, "TYPE");
4328 out_printf (outh, "#define %s ", str);
4331 out_printf (outh, "%s_get_type()\n", funcprefix);
4332 out_printf (outh, "GType %s_get_type (void)%s;\n\n",
4333 funcprefix, no_gnu ? "": " G_GNUC_CONST");
4336 "GType\n%s_get_type (void)\n"
4338 "\tstatic GType type = 0;\n"
4339 "\tif ___GOB_UNLIKELY(type == 0)\n"
4340 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
4343 funcprefix, type, funcprefix);
4345 g_free (funcprefix);
4350 print_flags (Flags *fnode)
4358 funcprefix = replace_sep (fnode->ftype, '_');
4359 gob_strdown (funcprefix);
4360 out_printf (out, "static const GFlagsValue _%s_values[] = {\n",
4362 type = remove_sep (fnode->ftype);
4364 out_printf (outh, "\ntypedef enum {\n");
4366 for (i = 0, li = fnode->values; li != NULL; i++, li = li->next) {
4367 const char *name = li->data;
4369 char *sname = gob_strdown (g_strdup (name));
4371 while ((p = strchr (sname, '_')) != NULL)
4374 out_printf (outh, "\t%s_%s = 1<<%d",
4375 fnode->prefix, name, i);
4376 if (li->next != NULL)
4377 out_printf (outh, ",\n");
4379 out_printf (outh, "\n");
4381 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
4382 fnode->prefix, name,
4383 fnode->prefix, name,
4389 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
4391 out_printf (outh, "} %s;\n", type);
4393 str = make_pre_macro (fnode->ftype, "TYPE");
4394 out_printf (outh, "#define %s ", str);
4397 out_printf (outh, "%s_get_type()\n", funcprefix);
4398 out_printf (outh, "GType %s_get_type (void)%s;\n\n",
4399 funcprefix, no_gnu ? "" : " G_GNUC_CONST");
4402 "GType\n%s_get_type (void)\n"
4404 "\tstatic GType type = 0;\n"
4405 "\tif ___GOB_UNLIKELY(type == 0)\n"
4406 "\t\ttype = g_flags_register_static (\"%s\", _%s_values);\n"
4409 funcprefix, type, funcprefix);
4411 g_free (funcprefix);
4416 print_error (Error *enode)
4423 funcprefix = replace_sep (enode->etype, '_');
4424 gob_strdown (funcprefix);
4425 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
4427 type = remove_sep (enode->etype);
4429 out_printf (outh, "\ntypedef enum {\n");
4431 for (li = enode->values; li != NULL; li = li->next) {
4432 const char *name = li->data;
4434 char *sname = gob_strdown (g_strdup (name));
4436 while ((p = strchr (sname, '_')) != NULL)
4439 out_printf (outh, "\t%s_%s", enode->prefix, name);
4440 if (li->next != NULL)
4441 out_printf (outh, ",\n");
4443 out_printf (outh, "\n");
4445 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
4446 enode->prefix, name,
4447 enode->prefix, name,
4453 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
4455 out_printf (outh, "} %s;\n", type);
4457 str = make_pre_macro (enode->etype, "TYPE");
4458 out_printf (outh, "#define %s ", str);
4461 out_printf (outh, "%s_get_type ()\n", funcprefix);
4462 out_printf (outh, "GType %s_get_type (void)%s;\n\n",
4463 funcprefix, no_gnu ? "" : " G_GNUC_CONST");
4466 "GType\n%s_get_type (void)\n"
4468 "\tstatic GType type = 0;\n"
4469 "\tif ___GOB_UNLIKELY(type == 0)\n"
4470 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
4473 funcprefix, type, funcprefix);
4475 out_printf (outh, "#define %s %s_quark ()\n", enode->prefix, funcprefix);
4476 out_printf (outh, "GQuark %s_quark (void);\n\n", funcprefix);
4478 str = replace_sep (enode->etype, '-');
4482 "GQuark\n%s_quark (void)\n"
4484 "\tstatic GQuark q = 0;\n"
4486 "\t\tq = g_quark_from_static_string (\"%s\");\n"
4493 g_free (funcprefix);
4498 generate_outfiles(void)
4502 print_file_comments();
4508 print_header_prefixes();
4510 print_useful_macros();
4514 print_more_useful_macros ();
4516 for (li = nodes; li != NULL; li = li->next) {
4517 Node *node = li->data;
4518 if (node->type == CCODE_NODE) {
4519 CCode *cc = (CCode *)node;
4520 if (cc->cctype != HT_CCODE &&
4521 cc->cctype != AT_CCODE &&
4522 cc->cctype != AD_CCODE)
4523 print_ccode_block ((CCode *)node);
4524 } else if (node->type == CLASS_NODE) {
4525 print_class_block ((Class *)node);
4526 } else if (node->type == ENUMDEF_NODE) {
4527 print_enum ((EnumDef *)node);
4528 } else if (node->type == FLAGS_NODE) {
4529 print_flags ((Flags *)node);
4530 } else if (node->type == ERROR_NODE) {
4531 print_error ((Error *)node);
4533 g_assert_not_reached();
4537 print_header_postfixes();
4540 static void print_version(void)
4542 printf("%s (%s) %s\n", PACKAGE_NAME, PACKAGE_TARNAME, PACKAGE_VERSION);
4543 puts("Copyright (C) 2013 George (Jiri) Lebl et al.");
4544 puts("Copyright (C) 2022 Nick Bowler");
4545 puts("License GPLv2+: GNU GPL version 2 or any later version");
4546 puts("This is free software: you are free to change and redistribute it.");
4547 puts("There is NO WARRANTY, to the extent permitted by law.");
4550 static void print_usage(FILE *f)
4552 fprintf(f, "Usage: %s [options] file.gob\n", g_get_prgname());
4554 fprintf(f, "Try '%s --help' for more information.\n",
4559 static void print_help(void)
4561 const struct option *opt;
4563 print_usage(stdout);
4565 puts("This is \"GObject Builder\": a simple preprocessor to help with\n"
4566 "implementing GObject types in C.");
4569 for (opt = lopts; opt->name; opt++) {
4570 struct lopt_help help;
4572 /* Don't display obsolete options that don't do anything */
4573 if (!opt->flag && !opt->val)
4576 if (!lopt_get_help(opt, &help))
4579 help_print_option(opt, help.arg, help.desc, 20);
4583 puts("End world hunger, donate to the World Food Programme: https://www.wfp.org/");
4587 * Called after getopt_long receives an --m4 argument. Immediately stop
4588 * processing options. Then all non-option arguments seen so far together
4589 * with all remaining arguments are appended to M4_COMMANDLINE. If m4_clean
4590 * is false, then M4_FLAGS is inserted before the first non-option argument,
4593 * The resulting string is returned, which should be freed by the caller.
4595 static char *parse_m4_options(int argc, char **argv, gboolean m4_clean)
4597 char **nonopt = NULL, *save_argv0, *ret;
4600 /* First, conclude getopt run and reset with remaining args */
4601 getopt_long(optind, argv, sopts, lopts, NULL);
4606 save_argv0 = argv[0];
4607 argv[0] = M4_COMMANDLINE;
4610 ret = g_strjoinv(" ", argv);
4611 argv[0] = save_argv0;
4615 /* Locate first non-option argument, if any. */
4616 while ((opt = getopt_long(argc, argv, "-", NULL, NULL)) != -1) {
4618 nonopt = &argv[optind-2];
4623 /* If there is a non-option but the above didn't see it, must be "--" */
4624 if (!nonopt && argv[optind])
4625 nonopt = &argv[optind-2];
4628 /* Found non-option, insert M4_FLAGS just before it. */
4629 char *save_argv[3] = { nonopt[0], nonopt[1], nonopt[2] };
4631 nonopt[1] = M4_FLAGS;
4633 nonopt[0] = g_strjoinv(" ", argv);
4635 nonopt[1] = save_argv[1];
4636 nonopt[2] = save_argv[2];
4637 ret = g_strjoinv(" ", nonopt);
4640 nonopt[0] = save_argv[0];
4642 /* Only options, not inserting M4_FLAGS. */
4643 ret = g_strjoinv(" ", argv);
4646 argv[0] = save_argv0;
4650 static int parse_options(int argc, char **argv)
4652 gboolean show_m4_dir = FALSE, m4_clean = FALSE;
4653 char *raw_file_sep = "-";
4657 while ((opt = getopt_long(argc, argv, sopts, lopts, NULL)) != -1) {
4663 output_dir = optarg;
4666 exit_on_warn = TRUE;
4669 raw_file_sep = optarg ? optarg : "";
4675 no_touch = no_touch_headers = TRUE;
4681 m4_commandline = parse_m4_options(argc, argv, m4_clean);
4687 if (optopt == '?') {
4693 /* Rewind getopt to get internal error messages. */
4694 optind = 0, opterr = 1;
4695 while (getopt_long(argc, argv, sopts, lopts, NULL)
4698 case 0: /* no-op or option set by flag */;
4702 filename = argv[optind];
4703 if (argc > optind+1) {
4704 char *s = g_strjoinv(" ", argv+optind+1);
4705 fprintf(stderr, "%s: Warning: excess arguments ignored: %s\n",
4706 g_get_prgname(), s);
4712 file_sep = raw_file_sep[0];
4713 if (raw_file_sep[0] && raw_file_sep[1]) {
4714 fprintf(stderr, "%s: Warning: --file-sep characters beyond the first are ignored\n",
4721 printf("%s\n", M4_INCLUDE_DIR);
4729 compare_and_move (const char *old_filename)
4731 char *new_filename = g_strconcat (old_filename, "#gob#", NULL);
4733 gboolean equal = FALSE;
4735 old_f = fopen (old_filename, "r");
4738 gboolean error = FALSE;
4740 new_f = fopen (new_filename, "r");
4749 new_n = fread (new_buf, 1, sizeof (new_buf), new_f);
4750 if (ferror (new_f)) {
4752 error_printf (GOB_ERROR, 0,
4753 "Can't read %s: %s",
4755 g_strerror (errno));
4759 old_n = fread (old_buf, 1, sizeof (old_buf), old_f);
4761 || feof (new_f) != feof (old_f)
4763 || memcmp (new_buf, old_buf, new_n) != 0)
4772 error_printf (GOB_ERROR, 0, "Can't open %s: %s",
4773 new_filename, g_strerror (errno));
4781 if (! equal && unlink (old_filename) != 0) {
4782 error_printf (GOB_ERROR, 0, "Can't remove %s: %s",
4783 old_filename, g_strerror (errno));
4789 if (unlink (new_filename) != 0)
4790 error_printf (GOB_ERROR, 0, "Can't remove %s: %s",
4791 new_filename, g_strerror (errno));
4793 if (rename (new_filename, old_filename) != 0)
4794 error_printf (GOB_ERROR, 0, "Can't rename %s to %s: %s",
4795 new_filename, old_filename,
4796 g_strerror (errno));
4800 g_free (new_filename);
4804 main(int argc, char *argv[])
4808 g_set_prgname(argc > 0 ? argv[0] : "gob2");
4810 rc = parse_options(argc, argv);
4812 print_usage(stderr);
4813 return EXIT_FAILURE;
4814 } else if (rc > 0) {
4815 return EXIT_SUCCESS;
4819 yyin = popen(m4_commandline, "r");
4821 fprintf(stderr, "Error: can't open pipe from '%s'\n",
4825 } else if(filename) {
4826 yyin = fopen(filename, "r");
4828 fprintf(stderr, "Error: can't open file '%s'\n",
4837 /* This is where parsing is done */
4840 error_print (GOB_ERROR, 0, "Parsing errors, quitting");
4842 /* close input file */
4843 if(use_m4) pclose(yyin);
4848 error_print (GOB_ERROR, 0, "no class defined");
4851 exit_on_error = FALSE;
4853 signals = count_signals ((Class *)class);
4854 set_properties = count_set_properties ((Class *)class) +
4855 count_set_arguments ((Class *)class);
4856 get_properties = count_get_properties ((Class *)class) +
4857 count_get_arguments ((Class *)class);
4858 overrides = count_overrides ((Class *)class);
4859 privates = count_privates ((Class *)class);
4860 protecteds = count_protecteds ((Class *)class);
4861 unreftors = count_unreftors ((Class *)class);
4862 destructors = count_destructors ((Class *)class);
4863 initializers = count_initializers ((Class *)class);
4864 glade_widgets = count_glade_widgets ((Class *)class);
4865 overrode_get_type = find_get_type ((Class *)class);
4868 make_inits ((Class *)class);
4870 find_constructor ((Class *)class);
4871 if (user_constructor != NULL)
4872 need_constructor = TRUE;
4874 find_dispose ((Class *)class);
4875 if (unreftors > 0 ||
4876 dispose_handler != NULL ||
4877 user_dispose_method != NULL)
4878 need_dispose = TRUE;
4880 find_finalize ((Class *)class);
4881 if (destructors > 0 ||
4883 user_finalize_method != NULL) {
4884 need_finalize = TRUE;
4887 check_bad_symbols ((Class *)class);
4888 check_duplicate_symbols ((Class *)class);
4889 check_duplicate_overrides ((Class *)class);
4890 check_duplicate_signals_args ((Class *)class);
4891 check_public_new ((Class *)class);
4892 check_vararg ((Class *)class);
4893 check_firstarg ((Class *)class);
4894 check_nonvoidempty ((Class *)class);
4895 check_signal_args ((Class *)class);
4896 check_property_types ((Class *)class);
4897 check_argument_types ((Class *)class);
4898 check_func_arg_checks ((Class *)class);
4899 check_func_attrs ((Class *)class);
4900 check_for_class_destructors ((Class *)class);
4902 exit_on_error = TRUE;
4907 any_special = setup_special_array ((Class *)class, special_array);
4911 generate_outfiles ();
4922 compare_and_move(outfilebase);
4924 if (no_touch_headers) {
4925 compare_and_move(outfilehbase);
4927 compare_and_move(outfilephbase);