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;
137 gboolean use_m4 = FALSE; /* preprocess sources with m4 */
138 char *m4_commandline = NULL;
139 #define M4_INCLUDE_DIR PKGDATADIR "/m4"
140 #define M4_BASE_FILENAME "gobm4.m4"
141 #define M4_FLAGS "-P -s -I" M4_INCLUDE_DIR " -DGOBM4_GOB_VERSION=" VERSION " " M4_BASE_FILENAME
142 #define M4_COMMANDLINE "m4"
144 int method_unique_id = 1;
149 filebase = replace_sep (((Class *)class)->otype, file_sep);
150 gob_strdown (filebase);
152 if (output_dir != NULL && output_dir[0] != '\0') {
153 fullfilebase = g_strdup_printf("%s%c%s", output_dir,
154 G_DIR_SEPARATOR, filebase);
156 fullfilebase = g_strdup (filebase);
159 funcbase = replace_sep (((Class *)class)->otype, '_');
160 gob_strdown (funcbase);
162 pfuncbase = replace_sep (((Class *)class)->ptype, '_');
163 gob_strdown (pfuncbase);
165 macrobase = replace_sep (((Class *)class)->otype, '_');
166 gob_strup (macrobase);
168 macrois = make_pre_macro (((Class *)class)->otype, "IS");
169 pmacrois = make_pre_macro (((Class *)class)->ptype, "IS");
171 macrotype = make_pre_macro (((Class *)class)->otype, "TYPE");
172 pmacrotype = make_pre_macro (((Class *)class)->ptype, "TYPE");
174 typebase = remove_sep (((Class *)class)->otype);
176 ptypebase = remove_sep (((Class *)class)->ptype);
180 get_gtk_doc (const char *id)
187 val = g_hash_table_lookup(gtk_doc_hash, id);
189 return g_strdup_printf("/**\n * %s_%s:\n%s **/\n",
191 val = g_hash_table_lookup(gtk_doc_hash, id);
193 return g_strdup_printf("/**\n * %s_%s:\n%s **/\n",
199 print_type(FILE *fp, const Type *t, gboolean postfix_to_stars)
203 s = get_type(t, postfix_to_stars);
204 out_printf(fp, "%s", s);
210 print_method (FILE *fp,
211 const char *typeprefix,
212 const char *nameprefix,
213 const char *subnameprefix,
214 const char *namepostfix,
215 const char *afterargs,
218 gboolean print_funcattrs,
219 gboolean one_arg_per_line,
220 gboolean no_funcbase,
221 gboolean kill_underscore,
222 gboolean first_unused,
228 out_printf(fp, "%s", typeprefix);
229 print_type(fp, m->mtype, TRUE);
234 out_printf(fp, "%s%s%s%s(",
235 nameprefix, subnameprefix, id, namepostfix);
237 out_printf(fp, "%s%s_%s%s%s(",
238 nameprefix, funcbase, subnameprefix, id,
242 for(li=m->args; li; li=g_list_next(li)) {
243 FuncArg *arg = li->data;
244 const char *unused = "";
247 ! for_cpp && /* g++ has a cow with this */
250 unused = " G_GNUC_UNUSED";
253 print_type(fp, arg->atype, FALSE);
255 out_printf (fp, "___fake___");
257 out_printf(fp, "%s%s%s,%s", arg->name,
258 arg->atype->postfix ?
259 arg->atype->postfix : "",
261 one_arg_per_line ? "\n\t\t\t\t\t" : " ");
263 out_printf(fp, "%s%s%s", arg->name,
264 arg->atype->postfix ?
265 arg->atype->postfix : "",
269 out_printf(fp, ",%s...",
270 one_arg_per_line ? "\n\t\t\t\t\t" : " ");
272 out_printf(fp, "void");
274 /* Slightly icky: sometimes we are called st m->funcattrs
275 hasn't been set, but if so it should be NULL since its been
277 if(print_funcattrs && m->funcattrs != NULL
278 && strlen(m->funcattrs) > 0) {
279 /* To keep the output neat, we trim off the trailing '\n'
280 from the end of funcattrs for a moment. */
281 size_t funcattrs_len = strlen(m->funcattrs);
282 gboolean funcattrs_chomped = FALSE;
283 if((m->funcattrs)[funcattrs_len - 1] == '\n') {
284 m->funcattrs[funcattrs_len - 1] = '\0';
285 funcattrs_chomped = TRUE;
287 out_printf(fp, "%s)\n%s%s", afterargs, m->funcattrs, postfix);
288 /* Put it back like it was (though it shouldn't matter). */
289 if (funcattrs_chomped) {
290 (m->funcattrs)[funcattrs_len - 1] = '\n';
294 out_printf(fp, "%s)%s", afterargs, postfix);
299 any_method_to_alias(Class *c)
303 for(li=c->nodes;li;li=g_list_next(li)) {
304 Node *node = li->data;
305 if(node->type == METHOD_NODE) {
306 Method *m = (Method *)node;
308 if(m->method == INIT_METHOD ||
309 m->method == CLASS_INIT_METHOD ||
310 m->method == CONSTRUCTOR_METHOD ||
311 m->method == DISPOSE_METHOD ||
312 m->method == FINALIZE_METHOD ||
313 m->method == OVERRIDE_METHOD)
324 make_method_aliases (Class *c)
328 for(li = c->nodes; li != NULL; li = li->next) {
329 Node *node = li->data;
330 if(node->type == METHOD_NODE) {
331 Method *m = (Method *)node;
333 if(m->method == INIT_METHOD ||
334 m->method == CLASS_INIT_METHOD ||
335 m->method == CONSTRUCTOR_METHOD ||
336 m->method == DISPOSE_METHOD ||
337 m->method == FINALIZE_METHOD ||
338 m->method == OVERRIDE_METHOD)
341 out_printf (out, "#define self_%s %s_%s\n",
350 add_bad_hack_to_avoid_unused_warnings(const Class *c)
354 /* if we haven't had any methods, just return */
359 out_printf(out, "\n\n#if (!defined __GNUC__) || (defined __GNUC__ && defined __STRICT_ANSI__)\n");
361 "/*REALLY BAD HACK\n"
362 " This is to avoid unused warnings if you don't call\n"
363 " some method. I need to find a better way to do\n"
364 " this, not needed in GCC since we use some gcc\n"
365 " extentions to make saner, faster code */\n"
367 "___%s_really_bad_hack_to_avoid_warnings(void)\n"
369 out_printf(out, "\t((void (*)(void))GET_NEW_VARG)();\n");
370 for(li=c->nodes;li;li=g_list_next(li)) {
371 Node *node = li->data;
372 if(node->type == METHOD_NODE) {
373 Method *m = (Method *)node;
375 if(m->method == INIT_METHOD ||
376 m->method == CLASS_INIT_METHOD ||
377 m->method == CONSTRUCTOR_METHOD ||
378 m->method == DISPOSE_METHOD ||
379 m->method == FINALIZE_METHOD ||
380 m->method == OVERRIDE_METHOD)
383 /* in C++ mode we don't alias new */
384 if(for_cpp && strcmp(m->id, "new")==0)
387 out_printf(out, "\t((void (*)(void))self_%s)();\n", m->id);
390 out_printf(out, "\t___%s_really_bad_hack_to_avoid_warnings();\n",
393 out_printf(out, "}\n#endif /* !__GNUC__ || (__GNUC__ && __STRICT_ANSI__) */\n\n");
395 out_printf(out, "}\n\n");
399 put_variable(const Variable *v, FILE *fp)
401 out_printf(fp, "\t");
402 print_type(fp, v->vtype, FALSE);
403 out_printf(fp, "%s%s;", v->id,
405 v->vtype->postfix:"");
406 if(v->scope == PROTECTED_SCOPE)
407 out_printf(fp, " /* protected */");
408 out_printf(fp, "\n");
412 put_vs_method(const Method *m)
414 if(m->method != SIGNAL_LAST_METHOD &&
415 m->method != SIGNAL_FIRST_METHOD &&
416 m->method != VIRTUAL_METHOD)
419 /* if a signal mark it as such */
420 if(m->method != VIRTUAL_METHOD)
421 print_method(outh, "\t/*signal*/", "(* ", "", ") ", "", ";\n",
422 m, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE);
424 print_method(outh, "\t", "(* ", "", ") ", "", ";\n",
425 m, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE);
430 put_pub_method(const Method *m)
432 if(m->scope != PUBLIC_SCOPE)
435 out_addline_infile(outh, m->line_no);
436 print_method(outh, "", "\t", "", "\t", "", ";\n", m,
437 TRUE, TRUE, FALSE, TRUE, FALSE, FALSE);
438 out_addline_outfile(outh);
442 put_signal_macro (const Method *m, gboolean gnu)
444 if(m->method != SIGNAL_LAST_METHOD &&
445 m->method != SIGNAL_FIRST_METHOD)
450 out_printf (outh, "#define %s_connect__%s(object,func,data)\t"
451 "g_signal_connect(%s(object),\"%s\","
452 "(GCallback)(func),(data))\n",
453 funcbase, m->id, macrobase, m->id);
456 out_printf (outh, "#define %s_connect_after__%s(object,func,data)\t"
457 "g_signal_connect_after(%s(object),\"%s\","
458 "(GCallback)(func),(data))\n",
459 funcbase, m->id, macrobase, m->id);
462 out_printf (outh, "#define %s_connect_data__%s"
463 "(object,func,data,destroy_data,flags)\t"
464 "g_signal_connect_data(%s(object),\"%s\","
465 "(GCallback)(func),(data),(destroy_data),(GConnectFlags)(flags))\n",
466 funcbase, m->id, macrobase, m->id);
469 out_printf (outh, "#define %s_connect__%s(object,func,data)\t"
471 "%s(__extension__ ({%s *___object = (object); ___object; })),"
473 "(GCallback) __extension__ ({",
474 funcbase, m->id, macrobase, typebase, m->id);
475 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
476 " = (func); ", m, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE);
477 out_printf (outh, "___%s; }), (data))\n", m->id);
480 out_printf (outh, "#define %s_connect_after__%s(object,func,data)\t"
481 "g_signal_connect_after("
482 "%s(__extension__ ({%s *___object = (object); ___object; })),"
484 "(GCallback) __extension__ ({",
485 funcbase, m->id, macrobase, typebase, m->id);
486 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
487 " = (func); ", m, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE);
488 out_printf (outh, "___%s; }), (data))\n", m->id);
491 out_printf (outh, "#define %s_connect_data__%s"
492 "(object,func,data,destroy_data,flags)\t"
493 "g_signal_connect_data("
494 "%s(__extension__ ({%s *___object = (object); ___object; })),"
496 "(GCallback) __extension__ ({",
497 funcbase, m->id, macrobase, typebase, m->id);
498 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
499 " = (func); ", m, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE);
500 out_printf (outh, "___%s; }), (data), (destroy_data), (GConnectFlags)(flags))\n", m->id);
505 put_signal_macros (const Class *c, gboolean gnu)
512 for (li = c->nodes; li != NULL; li = li->next) {
513 const Node *n = li->data;
514 if (n->type == METHOD_NODE)
515 put_signal_macro ((Method *)n, gnu);
520 put_local_signal_macro (const Method *m)
522 if(m->method != SIGNAL_LAST_METHOD &&
523 m->method != SIGNAL_FIRST_METHOD)
527 out_printf (out, "#define self_connect__%s(object,func,data)\t"
528 "%s_connect__%s((object),(func),(data))\n",
529 m->id, funcbase, m->id);
532 out_printf (out, "#define self_connect_after__%s(object,func,data)\t"
533 "%s_connect_after__%s((object),(func),(data))\n",
534 m->id, funcbase, m->id);
537 out_printf (out, "#define self_connect_data__%s(object,func,data,destroy_data,flags)\t"
538 "%s_connect_data__%s((object),(func),(data),(destroy_data),(flags))\n",
539 m->id, funcbase, m->id);
543 put_local_signal_macros (const Class *c)
550 for (li = c->nodes; li != NULL; li = li->next) {
551 const Node *n = li->data;
552 if (n->type == METHOD_NODE)
553 put_local_signal_macro ((Method *)n);
559 put_prot_method(const Method *m)
563 if(m->scope != PROTECTED_SCOPE)
566 f = outph ? outph : out;
568 out_addline_infile(f, m->line_no);
569 print_method(f, "", "\t", "", "\t", "", ";\n",
570 m, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE);
571 out_addline_outfile(f);
575 put_priv_method_prot(const Method *m)
577 if(m->method == SIGNAL_LAST_METHOD ||
578 m->method == SIGNAL_FIRST_METHOD ||
579 m->method == VIRTUAL_METHOD) {
582 "static ", "___real_", "", " ", "", ";\n",
583 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
585 /* no else, here, it might still have a private prototype, it's not
588 if((m->method == OVERRIDE_METHOD &&
591 char *s = g_strdup_printf("___%x_", (guint)m->unique_id);
593 out_addline_infile(out, m->line_no);
594 print_method(out, "static ", s, "", " ", "",
595 no_gnu?";\n":" G_GNUC_UNUSED;\n",
596 m, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE);
598 out_addline_outfile(out);
600 } else if(m->scope == PRIVATE_SCOPE ||
601 m->method == INIT_METHOD ||
602 m->method == CLASS_INIT_METHOD ||
603 m->method == CONSTRUCTOR_METHOD ||
604 m->method == DISPOSE_METHOD ||
605 m->method == FINALIZE_METHOD) {
607 out_addline_infile(out, m->line_no);
608 print_method(out, "static ", "", "", " ", "",
609 no_gnu?";\n":" G_GNUC_UNUSED;\n",
610 m, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE);
612 out_addline_outfile(out);
617 make_func_arg (const char *typename, gboolean is_class, const char *name)
624 tn = g_strconcat (typename, ":Class", NULL);
626 tn = g_strdup (typename);
628 type = node_new (TYPE_NODE,
632 node = node_new (FUNCARG_NODE,
633 "atype:steal", (Type *)type,
636 return g_list_prepend (NULL, node);
640 make_inits(Class *cl)
642 int got_class_init = FALSE;
643 int got_init = FALSE;
646 for(li=cl->nodes;li;li=g_list_next(li)) {
648 if(n->type == METHOD_NODE) {
649 Method *m = (Method *)n;
650 if(m->method == INIT_METHOD) {
652 error_print(GOB_ERROR, m->line_no, "init defined more then once");
654 } else if(m->method == CLASS_INIT_METHOD) {
656 error_print(GOB_ERROR, m->line_no, "class_init defined more then once");
657 got_class_init = TRUE;
661 if(!got_class_init) {
662 Type *type = (Type *)node_new (TYPE_NODE,
665 node = node_new (METHOD_NODE,
667 "method", CLASS_INIT_METHOD,
670 "args:steal", make_func_arg (cl->otype,
673 "unique_id", method_unique_id++,
675 cl->nodes = g_list_prepend(cl->nodes, node);
678 Type *type = (Type *)node_new (TYPE_NODE,
681 node = node_new (METHOD_NODE,
683 "method", INIT_METHOD,
686 "args:steal", make_func_arg (cl->otype,
687 FALSE /* is_class */,
689 "unique_id", method_unique_id++,
691 cl->nodes = g_list_prepend(cl->nodes, node);
696 find_method(const Class *cl, int method, const char *id)
700 for(li=cl->nodes;li;li=g_list_next(li)) {
702 if(n->type == METHOD_NODE) {
703 Method *m = (Method *)n;
704 if (m->method == method
705 && (id == NULL || strcmp(m->id, id)==0))
714 find_constructor(const Class *cl)
716 user_constructor = find_method(cl, CONSTRUCTOR_METHOD, NULL);
720 find_dispose(const Class *cl)
722 dispose_handler = find_method(cl, OVERRIDE_METHOD, "dispose");
723 if (dispose_handler != NULL) {
724 if(strcmp(dispose_handler->otype, "G:Object") != 0)
725 error_print(GOB_ERROR, dispose_handler->line_no,
726 "dispose method override "
727 "of class other then "
729 if(g_list_length(dispose_handler->args) != 1)
730 error_print(GOB_ERROR, dispose_handler->line_no,
731 "dispose method override "
732 "with more then one "
736 user_dispose_method = find_method(cl, DISPOSE_METHOD, NULL);
740 find_finalize(const Class *cl)
742 finalize_handler = find_method(cl, OVERRIDE_METHOD, "finalize");
743 if (finalize_handler != NULL) {
744 if(strcmp(finalize_handler->otype, "G:Object") != 0)
745 error_print(GOB_ERROR, finalize_handler->line_no,
746 "finalize method override "
747 "of class other then "
749 if(g_list_length(finalize_handler->args) != 1)
750 error_print(GOB_ERROR, finalize_handler->line_no,
751 "finalize method override "
752 "with more then one "
756 user_finalize_method = find_method(cl, FINALIZE_METHOD, NULL);
760 /* hash of method -> name of signal prototype */
761 static GHashTable *marsh = NULL;
763 /* list of methods with different signal prototypes,
764 we check this list if we can use a signal prototype of a
765 previous signal method, there are only uniques here */
766 static GList *eq_signal_methods = NULL;
768 /* compare a list of strings */
770 is_list_equal(const GList *a, const GList *b)
772 for(;a && b; a=a->next, b=b->next) {
773 if(strcmp(a->data, b->data)!=0) {
777 /* the the lists were different length */
784 find_same_type_signal(const Method *m)
787 for(li=eq_signal_methods;li;li=li->next) {
788 Method *mm = li->data;
789 if(is_list_equal(mm->gtktypes, m->gtktypes))
796 print_signal_marsal_args (const Method *m)
798 if (strcmp (m->gtktypes->next->data, "NONE") != 0) {
801 for (i = 0, li = m->gtktypes->next;
803 i++, li = li->next) {
806 if (strcmp (li->data, "UNICHAR") == 0)
807 /* hack because glib is braindamaged */
808 get_func = g_strdup ("g_value_get_uint");
809 else if (strncmp(li->data, "BOXED_", 6) == 0)
810 get_func = g_strdup ("g_value_get_boxed");
812 get_func = g_strdup_printf
813 ("g_value_get_%s", (char *)li->data);
815 gob_strdown (get_func);
816 out_printf (out, ",\n\t\t(%s) "
817 "%s (param_values + %d)",
818 get_cast (li->data, FALSE),
823 out_printf (out, ",\n\t\tdata2);\n");
828 add_signal_prots(Method *m)
834 gboolean ret_none = FALSE;
835 gboolean arglist_none = FALSE;
837 const char *unused = "";
839 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
840 unused = " G_GNUC_UNUSED";
843 if (m->method != SIGNAL_LAST_METHOD &&
844 m->method != SIGNAL_FIRST_METHOD)
848 marsh = g_hash_table_new(NULL, NULL);
850 g_assert (m->gtktypes->next != NULL);
852 ret_none = strcmp(m->gtktypes->data, "NONE") == 0;
853 arglist_none = strcmp(m->gtktypes->next->data, "NONE") == 0;
855 if (ret_none && arglist_none)
858 /* if we already did a signal prototype just use that */
859 mm = find_same_type_signal (m);
861 s = g_hash_table_lookup (marsh, mm);
862 g_hash_table_insert (marsh, m, s);
869 retcast = get_cast (m->gtktypes->data, FALSE);
871 s = g_strdup_printf("Sig%d", sig++);
873 g_hash_table_insert(marsh, m, s);
874 eq_signal_methods = g_list_prepend(eq_signal_methods, m);
876 /* we know that we'll know all the gtktypes (so get_cast can't fail) */
877 out_printf(out, "\ntypedef %s (*___%s) (%s *, ",
878 get_cast(m->gtktypes->data, FALSE), s, typebase);
880 if ( ! arglist_none) {
881 for (li = m->gtktypes->next; li != NULL; li = li->next)
882 out_printf (out, "%s, ", get_cast (li->data, FALSE));
884 out_printf (out, "gpointer);\n");
886 out_printf (out, "\nstatic void\n"
887 "___marshal_%s (GClosure *closure,\n"
888 "\tGValue *return_value%s,\n"
889 "\tguint n_param_values,\n"
890 "\tconst GValue *param_values,\n"
891 "\tgpointer invocation_hint%s,\n"
892 "\tgpointer marshal_data)\n"
899 out_printf (out, "\t%s v_return;\n", retcast);
901 out_printf (out, "\tregister ___%s callback;\n"
902 "\tregister GCClosure *cc = (GCClosure*) closure;\n"
903 "\tregister gpointer data1, data2;\n\n",
906 out_printf (out, "\tg_return_if_fail (n_param_values == %d);\n\n",
907 arglist_none ? 1 : g_list_length (m->gtktypes));
910 "\tif (G_CCLOSURE_SWAP_DATA (closure)) {\n"
911 "\t\tdata1 = closure->data;\n"
912 "\t\tdata2 = g_value_peek_pointer (param_values + 0);\n"
914 "\t\tdata1 = g_value_peek_pointer (param_values + 0);\n"
915 "\t\tdata2 = closure->data;\n"
918 out_printf (out, "\tcallback = (___%s) "
919 "(marshal_data != NULL ? marshal_data : cc->callback);"
923 out_printf (out, "\tcallback ((%s *)data1", typebase);
925 out_printf (out, "\tv_return = callback ((%s *)data1",
929 print_signal_marsal_args (m);
932 /* FIXME: This code is so fucking ugly it hurts */
933 gboolean take_ownership =
934 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
935 strcmp ((char *)m->gtktypes->data, "BOXED") == 0);
939 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
940 /* hack because glib is braindamaged */
941 set_func = g_strdup ("g_value_set_uint");
943 set_func = g_strdup_printf ("g_value_%s_%s",
946 (char *)m->gtktypes->data);
947 gob_strdown (set_func);
949 out_printf (out, "\n\t%s (return_value, v_return);\n",
954 if (no_gnu || for_cpp /* g++ has a cow with G_GNUC_UNUSED */) {
956 out_printf (out, "\n\treturn_value = NULL;\n");
957 out_printf (out, "\tinvocation_hint = NULL;\n");
960 out_printf (out, "}\n\n");
964 interface_type(const char *if_name)
966 char *rawtype = remove_sep(if_name);
967 char *end = "", *typename;
971 * EEEK! evil, we should have some sort of option
972 * to force this for arbitrary interfaces, since
973 * some are Class and some are Iface. Glib is shite
977 if (strcmp (rawtype, "GtkEditable") == 0
978 || strcmp (rawtype, "GTypePlugin") == 0)
982 /* We'll assume Iface is the standard ending */
986 /* GTK3 doesn't need Iface end */
990 typename = g_strconcat(rawtype, end, (char *)NULL);
997 define_parent_interface_refs(Class *c)
1004 out_printf(out, "\n/* parent class interface implementations */\n");
1005 for (li = c->interfaces; li != NULL; li = li->next) {
1006 char *name = replace_sep(li->data, '_');
1007 char *type = interface_type(li->data);
1009 out_printf (out, "static %s *%s_parent_iface;\n", type, name);
1020 out_printf(out, "\n");
1022 out_printf(out, "enum {\n");
1023 for(li=c->nodes;li;li=g_list_next(li)) {
1025 if(n->type == METHOD_NODE) {
1026 Method *m = (Method *)n;
1027 if(m->method == SIGNAL_LAST_METHOD ||
1028 m->method == SIGNAL_FIRST_METHOD) {
1029 char *s = g_strdup(m->id);
1031 out_printf(out, "\t%s_SIGNAL,\n", s);
1036 out_printf(out, "\tLAST_SIGNAL\n};\n\n");
1038 if (set_properties > 0 ||
1039 get_properties > 0) {
1040 out_printf(out, "enum {\n\tPROP_0");
1041 for(li=c->nodes;li;li=g_list_next(li)) {
1043 if (n->type == PROPERTY_NODE) {
1044 Property *p = (Property *)n;
1045 char *s = g_strdup (p->name);
1047 out_printf (out, ",\n\tPROP_%s", s);
1049 } else if (n->type == ARGUMENT_NODE) {
1050 Argument *a = (Argument *)n;
1051 char *s = g_strdup(a->name);
1053 out_printf(out, ",\n\tPROP_%s", s);
1057 out_printf(out, "\n};\n\n");
1062 "static guint object_signals[LAST_SIGNAL] = {0};\n\n");
1064 out_printf(out, "/* pointer to the class of our parent */\n");
1065 out_printf(out, "static %sClass *parent_class = NULL;\n", ptypebase);
1066 define_parent_interface_refs(c);
1067 out_printf(out, "\n");
1071 add_interface_methods (Class *c, const char *interface)
1074 gboolean added_line = FALSE;
1076 for (li = c->nodes; li != NULL; li = li->next) {
1078 Method *m = (Method *)n;
1079 if (n->type != METHOD_NODE ||
1080 m->method == OVERRIDE_METHOD ||
1081 m->interface == NULL ||
1082 strcmp (m->interface, interface) != 0)
1085 if (m->line_no > 0) {
1086 out_addline_infile (out, m->line_no);
1088 } else if (m->line_no == 0 &&
1090 out_addline_outfile (out);
1093 out_printf (out, "\tiface->%s = self_%s;\n",
1097 out_addline_outfile (out);
1101 add_interface_inits(Class *c)
1105 if (c->interfaces == NULL)
1108 out_printf(out, "\n");
1110 for (li = c->interfaces; li != NULL; li = li->next) {
1111 char *name = replace_sep(li->data, '_');
1112 char *type = interface_type(li->data);
1114 out_printf(out, "static void\n"
1115 "___%s_init (%s *iface)\n"
1118 add_interface_methods(c, li->data);
1120 out_printf(out, "\t%s_parent_iface\n", name);
1121 out_printf(out, for_cpp ? "\t\t= (%s *)" : "\t\t= ", type);
1122 out_printf(out, "g_type_interface_peek_parent(iface);\n"
1131 add_interface_infos(Class *c, gboolean static_storage)
1135 for (li = c->interfaces; li; li = li->next) {
1136 char *name = replace_sep(li->data, '_');
1137 out_printf(out, "\t%sconst GInterfaceInfo %s_info = {\n"
1138 "\t\t(GInterfaceInitFunc) ___%s_init,\n"
1142 static_storage ? "static " : "",
1147 out_printf(out, "\n");
1151 define_add_interfaces(Class *c)
1158 out_printf(out, "static void ___add_interfaces(GType type)\n{\n");
1159 add_interface_infos(c, TRUE);
1161 for (li = c->interfaces; li; li = li->next) {
1162 char *type = make_pre_macro(li->data, "TYPE");
1163 char *name = replace_sep(li->data, '_');
1165 out_printf(out, "\tg_type_add_interface_static\n"
1176 out_printf(out, "}\n\n");
1180 define_dynamic_add_interfaces(Class *c)
1187 out_printf(out, "static void ___add_interfaces"
1188 "(GTypeModule *type_module, GType type)\n"
1190 add_interface_infos(c, FALSE);
1193 * Hack to work around bug in g_type_module_add_interface,
1194 * which will fail to add an interface to types that derive
1195 * from something that also implements the same interface.
1197 * The actual GType system does not have any such problem,
1198 * and the GTypeModule implementation details relied upon
1199 * here have not changed once since the feature was first
1200 * implemented almost 20 years ago.
1202 out_printf(out, "\tstruct _ModuleInterfaceInfo {\n"
1203 "\t\tgboolean loaded;\n"
1204 "\t\tGType instance_type;\n"
1205 "\t\tGType interface_type;\n"
1206 "\t\tGInterfaceInfo info;\n"
1209 for (li = c->interfaces; li; li = li->next) {
1210 char *type = make_pre_macro(li->data, "TYPE");
1211 char *name = replace_sep(li->data, '_');
1213 out_printf(out, "\n"
1214 "\tmodinfo = g_malloc(sizeof *modinfo);\n"
1215 "\tmodinfo->loaded = TRUE;\n"
1216 "\tmodinfo->instance_type = type;\n"
1217 "\tmodinfo->interface_type = %s;\n"
1218 "\tmodinfo->info = %s_info;\n"
1219 "\tg_type_add_interface_dynamic\n"
1220 "\t\t( modinfo->instance_type\n"
1221 "\t\t, modinfo->interface_type\n"
1222 "\t\t, G_TYPE_PLUGIN(type_module)\n"
1224 "\ttype_module->interface_infos = g_slist_prepend\n"
1225 "\t\t( type_module->interface_infos\n"
1234 out_printf(out, "}\n\n");
1237 static void define_add_privates(Class *c)
1239 const char *addprivate = c->dynamic
1240 ? "G_ADD_PRIVATE_DYNAMIC"
1246 out_printf(out, "#ifdef %s\n"
1247 "#define ___add_privates() %s(%s)\n"
1249 "#define ___add_privates()\n"
1251 addprivate, addprivate, typebase);
1254 static void add_type_info(void)
1256 out_printf(out, "\tstatic const GTypeInfo info = {\n"
1257 "\t\tsizeof (%sClass),\n"
1258 "\t\t(GBaseInitFunc) NULL,\n"
1259 "\t\t(GBaseFinalizeFunc) NULL,\n"
1260 "\t\t(GClassInitFunc) %s_class_init,\n"
1261 "\t\t(GClassFinalizeFunc) NULL,\n"
1262 "\t\tNULL /* class_data */,\n"
1263 "\t\tsizeof (%s),\n"
1264 "\t\t%d /* n_preallocs */,\n"
1265 "\t\t(GInstanceInitFunc) %s_init,\n"
1268 typebase, funcbase, typebase, npreallocs, funcbase);
1274 Class *c = (Class *)class;
1276 define_add_interfaces(c);
1277 define_add_privates(c);
1279 out_printf(out, "#ifdef G_DEFINE_TYPE_EXTENDED\n\n"
1280 "G_DEFINE_TYPE_EXTENDED(%s, %s, %s,\n"
1281 "\t(GTypeFlags)%s,\n",
1282 typebase, funcbase, pmacrotype,
1283 c->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0");
1286 out_printf(out, "\t___add_privates();\n");
1289 out_printf(out, "\t___add_interfaces(g_define_type_id);\n");
1291 /* Fallback for GLib < 2.4 */
1292 out_printf(out, ");\n\n"
1294 "GType %s_get_type(void)\n"
1296 "\tstatic GType type = 0;\n",
1301 out_printf(out, "\tif ___GOB_UNLIKELY(type == 0) {\n"
1302 "\t\ttype = g_type_register_static\n"
1306 "\t\t\t, (GTypeFlags)%s\n"
1308 pmacrotype, typebase,
1309 c->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0");
1312 out_printf(out, "\t\t___add_interfaces(type);\n");
1314 out_printf(out, "\t}\n\n"
1321 add_dynamic_get_type(void)
1323 Class *c = (Class *)class;
1325 define_dynamic_add_interfaces(c);
1326 define_add_privates(c);
1329 * G_DEFINE_DYNAMIC_TYPE_EXTENDED is usable if available, except for
1330 * some reason it defines an xxx_register_type function with internal
1331 * linkage. This is kind of weird so we have to work around that.
1333 out_printf(out, "#ifdef G_DEFINE_DYNAMIC_TYPE_EXTENDED\n\n"
1334 "static void %s_class_finalize(%sClass *c) { }\n\n"
1335 "#define %s_register_type ___register_type\n",
1336 funcbase, typebase, funcbase);
1338 out_printf(out, "G_DEFINE_DYNAMIC_TYPE_EXTENDED(%s, %s, %s,\n"
1339 "\t(GTypeFlags)%s,\n",
1340 typebase, funcbase, pmacrotype,
1341 c->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0");
1344 out_printf(out, "\t___add_privates();\n");
1346 if (c->interfaces) {
1347 out_printf(out, "\t___add_interfaces"
1348 "(type_module, %s_type_id);\n", funcbase);
1351 out_printf(out, ");\n"
1352 "#undef %s_register_type\n\n"
1353 "void %s_register_type(GTypeModule *type_module)\n"
1355 "\t___register_type(type_module);\n"
1357 funcbase, funcbase);
1359 /* Fallback for GLib < 2.14 */
1360 out_printf(out, "#else\n\n"
1361 "static GType %s_type_id;\n\n"
1362 "GType %s_get_type(void)\n"
1364 "\treturn %s_type_id;\n"
1366 funcbase, funcbase, funcbase);
1368 out_printf(out, "void %s_register_type(GTypeModule *type_module)\n"
1374 out_printf(out, "\t%s_type_id = g_type_module_register_type\n"
1375 "\t\t( type_module\n"
1379 "\t\t, (GTypeFlags)%s\n"
1381 funcbase, pmacrotype, typebase,
1382 c->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0");
1384 if (c->interfaces) {
1385 out_printf(out, "\t___add_interfaces"
1386 "(type_module, %s_type_id);\n",
1390 out_printf(out, "}\n\n"
1395 add_bonobo_object_get_type(void)
1397 Class *c = (Class *)class;
1399 define_add_interfaces(c);
1401 out_printf (out, "GType %s_get_type(void)\n"
1403 "\tstatic GType type = 0;\n",
1408 out_printf (out, "\tif ___GOB_UNLIKELY(type == 0) {\n"
1409 "\t\ttype = bonobo_type_unique\n"
1410 "\t\t\t( BONOBO_OBJECT_TYPE\n"
1411 "\t\t\t, POA_%s__init, NULL\n"
1412 "\t\t\t, G_STRUCT_OFFSET (%sClass, _epv)\n"
1416 c->bonobo_object_class, typebase, typebase);
1418 if (((Class *)class)->interfaces)
1419 out_printf(out, "\t\t___add_interfaces(type);\n");
1421 out_printf(out, "\t}\n\n"
1427 add_overrides(Class *c, const char *oname,
1428 gboolean did_base_obj)
1434 done = g_hash_table_new (g_str_hash, g_str_equal);
1436 s = g_strdup ("GObject");
1437 g_hash_table_insert (done, s, s);
1439 for (li = c->nodes; li != NULL; li = li->next) {
1442 Method *m = (Method *)n;
1443 if(n->type != METHOD_NODE ||
1444 m->method != OVERRIDE_METHOD)
1447 s = remove_sep(m->otype);
1449 if(g_hash_table_lookup(done, s)) {
1453 g_hash_table_insert(done, s, s);
1455 f = replace_sep(m->otype, '_');
1458 out_printf(out, "\t%sClass *%s_class = (%sClass *)%s;\n",
1463 g_hash_table_foreach (done, (GHFunc)g_free, NULL);
1464 g_hash_table_destroy (done);
1468 make_run_signal_flags(Method *m, gboolean last)
1483 gs = g_string_new(NULL);
1486 g_string_assign(gs, "G_SIGNAL_RUN_LAST");
1488 g_string_assign(gs, "G_SIGNAL_RUN_FIRST");
1490 if(m->scope == PUBLIC_SCOPE)
1491 g_string_append(gs, " | G_SIGNAL_ACTION");
1493 for(li = m->flags; li; li = li->next) {
1494 char *flag = li->data;
1496 for(i=0;flags[i];i++) {
1497 if(strcmp(flags[i], flag)==0)
1500 /* if we haven't found it in our list */
1502 error_printf(GOB_WARN, m->line_no,
1503 "Unknown flag '%s' used, "
1504 "perhaps it was misspelled",
1507 g_string_append_printf(gs, " | G_SIGNAL_%s", flag);
1511 char *ret = gs->str;
1512 g_string_free(gs, FALSE);
1519 add_signals(Class *c)
1523 out_printf(out, "\n");
1524 for(li=c->nodes;li;li=g_list_next(li)) {
1526 char *mar, *sig, *flags;
1527 gboolean is_none, last = FALSE;
1528 Method *m = (Method *)n;
1530 if(n->type != METHOD_NODE ||
1531 (m->method != SIGNAL_FIRST_METHOD &&
1532 m->method != SIGNAL_LAST_METHOD))
1535 if(m->method == SIGNAL_FIRST_METHOD)
1540 if(g_hash_table_lookup(marsh, m))
1541 mar = g_strconcat("___marshal_",
1542 (char *)g_hash_table_lookup(marsh, m),
1545 mar = g_strdup("g_cclosure_marshal_VOID__VOID");
1547 is_none = (strcmp(m->gtktypes->next->data, "NONE")==0);
1549 sig = g_strdup (m->id);
1551 flags = make_run_signal_flags (m, last);
1552 out_printf (out, "\tobject_signals[%s_SIGNAL] =\n"
1553 "\t\tg_signal_new (%s,\n"
1554 "\t\t\tG_TYPE_FROM_CLASS (g_object_class),\n"
1555 "\t\t\t(GSignalFlags)(%s),\n"
1556 "\t\t\tG_STRUCT_OFFSET (%sClass, %s),\n"
1557 "\t\t\tNULL, NULL,\n"
1559 "\t\t\tG_TYPE_%s, %d",
1560 sig, m->signal_name /*m->id* if not given signal_name*/,
1562 typebase, m->id, mar,
1563 (char *)m->gtktypes->data,
1564 is_none ? 0 : g_list_length(m->gtktypes->next));
1572 for(l = m->gtktypes->next; l != NULL; l = l->next) {
1573 char *str = l->data;
1574 if (strncmp (str, "BOXED_", 6) == 0)
1575 t = g_strdup (&(str[6]));
1577 t = g_strconcat ("G_TYPE_", str, NULL);
1578 out_printf (out, ",\n\t\t\t%s", t);
1583 out_printf(out, ");\n");
1585 if(strcmp(m->gtktypes->data, "NONE") != 0 ||
1588 out_printf(out, "\tif ___GOB_UNLIKELY(");
1589 if(strcmp(m->gtktypes->data, "NONE") != 0) {
1590 out_printf(out, "sizeof(");
1591 print_type(out, m->mtype, FALSE);
1592 out_printf(out, "%s",
1594 m->mtype->postfix : "");
1595 out_printf(out, ") != sizeof(%s) || ",
1596 get_cast(m->gtktypes->data, FALSE));
1599 for(al = m->args->next, gl = m->gtktypes->next;
1600 al != NULL && gl != NULL;
1601 al = al->next, gl = gl->next) {
1602 FuncArg *arg = al->data;
1603 char *gtkarg = gl->data;
1605 out_printf(out, "sizeof(");
1606 print_type(out, arg->atype, FALSE);
1607 out_printf(out, "%s",
1608 arg->atype->postfix ?
1609 arg->atype->postfix : "");
1610 out_printf(out, ") != sizeof(%s) || ",
1611 get_cast(gtkarg, FALSE));
1615 "parent_class == NULL /* avoid warning */");
1617 out_printf(out, ") {\n"
1618 "\t\tg_error(\"%s line %d: Type mismatch "
1619 "of \\\"%s\\\" signal signature\");\n"
1621 filename, m->line_no, m->id);
1628 set_def_handlers(Class *c, const char *oname)
1631 gboolean set_line = FALSE;
1633 out_printf(out, "\n");
1634 for(li = c->nodes; li; li = g_list_next(li)) {
1636 Method *m = (Method *)n;
1638 if(n->type != METHOD_NODE ||
1639 (m->method != SIGNAL_FIRST_METHOD &&
1640 m->method != SIGNAL_LAST_METHOD &&
1641 m->method != VIRTUAL_METHOD &&
1642 m->method != OVERRIDE_METHOD))
1645 if(m->line_no > 0 && m->cbuf) {
1646 out_addline_infile(out, m->line_no);
1648 } else if(set_line) {
1649 out_addline_outfile(out);
1654 if (m->method == OVERRIDE_METHOD) {
1656 s = replace_sep (m->otype, '_');
1660 dispose_handler != NULL &&
1661 strcmp (m->id, "dispose") == 0)
1662 out_printf (out, "\tg_object_class->dispose "
1664 else if (need_finalize &&
1666 strcmp(m->id, "finalize") == 0)
1668 "\tg_object_class->finalize = ___finalize;\n");
1669 else if (m->cbuf != NULL)
1671 "\t%s_class->%s = ___%x_%s_%s;\n",
1672 s, m->id, (guint)m->unique_id,
1675 out_printf(out, "\t%s_class->%s = NULL;\n",
1679 out_printf(out, "\t%s->%s = ___real_%s_%s;\n",
1683 out_printf(out, "\t%s->%s = NULL;\n",
1688 out_addline_outfile(out);
1692 make_argument (Argument *a)
1697 char *argflags[] = {
1705 flags = g_string_new ("(GParamFlags)(");
1707 if(a->get && a->set)
1708 g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
1710 g_string_append (flags, "G_PARAM_READABLE");
1712 g_string_append (flags, "G_PARAM_WRITABLE");
1714 g_assert(a->get || a->set);
1716 for (l = a->flags; l != NULL; l = l->next) {
1717 char *flag = l->data;
1719 if(strcmp (flag, "READABLE") == 0 ||
1720 strcmp (flag, "WRITABLE") == 0) {
1721 error_print(GOB_WARN, a->line_no,
1723 "WRITABLE argument flags are "
1724 "set automatically");
1727 for(i = 0; argflags[i]; i++) {
1728 if(strcmp(argflags[i], flag)==0)
1731 g_string_append_printf(flags, " | %s%s", argflags[i] ? "G_PARAM_" : "", flag);
1734 g_string_append (flags, ")");
1736 s = g_strdup(a->name);
1738 if (!strcmp (a->gtktype, "ENUM"))
1739 out_printf(out, "\tparam_spec = g_param_spec_enum (\"%s\", NULL, NULL,\n"
1740 "\t\tG_TYPE_ENUM, 0,\n"
1742 a->name, flags->str);
1743 if (!strcmp (a->gtktype, "FLAGS"))
1744 out_printf(out, "\tparam_spec = g_param_spec_flags (\"%s\", NULL, NULL,\n"
1745 "\t\tG_TYPE_FLAGS, 0,\n"
1747 a->name, flags->str);
1748 else if (!strcmp (a->gtktype, "OBJECT"))
1749 out_printf(out, "\tparam_spec = g_param_spec_object (\"%s\", NULL, NULL,\n"
1750 "\t\tG_TYPE_OBJECT,\n"
1752 a->name, flags->str);
1753 else if (!strcmp (a->gtktype, "STRING"))
1754 out_printf(out, "\tparam_spec = g_param_spec_string (\"%s\", NULL, NULL,\n"
1757 a->name, flags->str);
1758 else if (!strcmp (a->gtktype, "INT"))
1759 out_printf(out, "\tparam_spec = g_param_spec_int (\"%s\", NULL, NULL,\n"
1760 "\t\tG_MININT, G_MAXINT,\n"
1763 a->name, flags->str);
1764 else if (!strcmp (a->gtktype, "UINT"))
1765 out_printf(out, "\tparam_spec = g_param_spec_uint (\"%s\", NULL, NULL,\n"
1766 "\t\t0, G_MAXUINT,\n"
1769 a->name, flags->str);
1770 else if (!strcmp (a->gtktype, "INT"))
1771 out_printf(out, "\tparam_spec = g_param_spec_int (\"%s\", NULL, NULL,\n"
1772 "\t\tG_MININT, G_MAXINT,\n"
1775 a->name, flags->str);
1776 else if (!strcmp (a->gtktype, "CHAR"))
1777 out_printf(out, "\tparam_spec = g_param_spec_char (\"%s\", NULL, NULL,\n"
1781 a->name, flags->str);
1782 else if (!strcmp (a->gtktype, "UCHAR"))
1783 out_printf(out, "\tparam_spec = g_param_spec_uchar (\"%s\", NULL, NULL,\n"
1787 a->name, flags->str);
1788 else if (!strcmp (a->gtktype, "BOOL") ||
1789 !strcmp (a->gtktype, "BOOLEAN"))
1790 out_printf(out, "\tparam_spec = g_param_spec_boolean (\"%s\", NULL, NULL,\n"
1793 a->name, flags->str);
1794 else if (!strcmp (a->gtktype, "LONG"))
1795 out_printf(out, "\tparam_spec = g_param_spec_long (\"%s\", NULL, NULL,\n"
1796 "\t\tG_MINLONG, G_MAXLONG,\n"
1799 a->name, flags->str);
1800 else if (!strcmp (a->gtktype, "ULONG"))
1801 out_printf(out, "\tparam_spec = g_param_spec_ulong (\"%s\", NULL, NULL,\n"
1802 "\t\t0, G_MAXULONG,\n"
1805 a->name, flags->str);
1806 else if (!strcmp (a->gtktype, "INT64"))
1807 out_printf(out, "\tparam_spec = g_param_spec_int64 (\"%s\", NULL, NULL,\n"
1808 "\t\tG_MININT64, G_MAXINT64,\n"
1811 a->name, flags->str);
1812 else if (!strcmp (a->gtktype, "UINT64"))
1813 out_printf(out, "\tparam_spec = g_param_spec_uint64 (\"%s\", NULL, NULL,\n"
1814 "\t\t0, G_MAXUINT64,\n"
1817 a->name, flags->str);
1818 else if (!strcmp (a->gtktype, "FLOAT"))
1819 out_printf(out, "\tparam_spec = g_param_spec_float (\"%s\", NULL, NULL,\n"
1820 "\t\t-G_MAXFLOAT, G_MAXFLOAT,\n"
1823 a->name, flags->str);
1824 else if (!strcmp (a->gtktype, "DOUBLE"))
1825 out_printf(out, "\tparam_spec = g_param_spec_double (\"%s\", NULL, NULL,\n"
1826 "\t\t-G_MAXDOUBLE, G_MAXDOUBLE,\n"
1829 a->name, flags->str);
1830 else if (!strcmp (a->gtktype, "POINTER"))
1831 out_printf(out, "\tparam_spec = g_param_spec_pointer (\"%s\", NULL, NULL,\n"
1833 a->name, flags->str);
1835 error_printf (GOB_ERROR, a->line_no,
1836 "%s type is not supported for arguments, try using properties",
1839 out_printf(out, "\tg_object_class_install_property (g_object_class,\n"
1840 "\t\tPROP_%s, param_spec);\n", s);
1844 g_string_free(flags, TRUE);
1847 #define value_for_print(str, alt) (str != NULL ? str : alt)
1850 make_property (Property *p)
1854 if (p->get == NULL && p->set == NULL) {
1855 error_print (GOB_ERROR, p->line_no,
1856 "Property has no getter nor setter");
1860 if (p->flags != NULL)
1861 error_print (GOB_WARN, p->line_no,
1862 "Overridden property, flags ignored");
1863 if (p->nick != NULL)
1864 error_print (GOB_WARN, p->line_no,
1865 "Overridden property, nick ignored");
1866 if (p->blurb != NULL)
1867 error_print (GOB_WARN, p->line_no,
1868 "Overridden property, blurb ignored");
1869 if (p->minimum != NULL)
1870 error_print (GOB_WARN, p->line_no,
1871 "Overridden property, minimum ignored");
1872 if (p->maximum != NULL)
1873 error_print (GOB_WARN, p->line_no,
1874 "Overridden property, maximum ignored");
1875 if (p->default_value != NULL)
1876 error_print (GOB_WARN, p->line_no,
1877 "Overridden property, default_value ignored");
1879 s = g_strdup (p->name);
1881 out_printf (out, "\tg_object_class_override_property (g_object_class,\n"
1883 "\t\t\"%s\");\n", s, value_for_print (p->canonical_name, p->name) );
1888 char *argflags[] = {
1896 flags = g_string_new ("(GParamFlags)(");
1898 if (p->get != NULL && p->set != NULL)
1899 g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
1900 else if (p->get != NULL)
1901 g_string_append (flags, "G_PARAM_READABLE");
1903 g_string_append (flags, "G_PARAM_WRITABLE");
1906 for (l = p->flags; l != NULL; l = l->next) {
1907 char *flag = l->data;
1909 if(strcmp (flag, "READABLE") == 0 ||
1910 strcmp (flag, "WRITABLE") == 0) {
1911 error_print(GOB_WARN, p->line_no,
1913 "WRITABLE argument flags are "
1914 "set automatically");
1917 for(i = 0; argflags[i]; i++) {
1918 if(strcmp(argflags[i], flag)==0)
1921 g_string_append_printf(flags, " | %s%s", argflags[i] ? "G_PARAM_" : "", flag);
1924 g_string_append (flags, ")");
1926 if (strcmp (p->gtktype, "CHAR") == 0) {
1927 out_printf (out, "\tparam_spec = g_param_spec_char\n"
1928 "\t\t(\"%s\" /* name */,\n"
1929 "\t\t %s /* nick */,\n"
1930 "\t\t %s /* blurb */,\n"
1931 "\t\t %s /* minimum */,\n"
1932 "\t\t %s /* maximum */,\n"
1933 "\t\t %s /* default_value */,\n"
1935 value_for_print (p->canonical_name, p->name),
1936 value_for_print (p->nick, "NULL"),
1937 value_for_print (p->blurb, "NULL"),
1938 value_for_print (p->minimum, "-128"),
1939 value_for_print (p->maximum, "127"),
1940 value_for_print (p->default_value, "0"),
1942 } else if (strcmp (p->gtktype, "UCHAR") == 0) {
1943 out_printf (out, "\tparam_spec = g_param_spec_uchar\n"
1944 "\t\t(\"%s\" /* name */,\n"
1945 "\t\t %s /* nick */,\n"
1946 "\t\t %s /* blurb */,\n"
1947 "\t\t %s /* minimum */,\n"
1948 "\t\t %s /* maximum */,\n"
1949 "\t\t %s /* default_value */,\n"
1951 value_for_print (p->canonical_name, p->name),
1952 value_for_print (p->nick, "NULL"),
1953 value_for_print (p->blurb, "NULL"),
1954 value_for_print (p->minimum, "0"),
1955 value_for_print (p->maximum, "0xFF"),
1956 value_for_print (p->default_value, "0"),
1958 } else if (strcmp (p->gtktype, "BOOLEAN") == 0) {
1959 out_printf (out, "\tparam_spec = g_param_spec_boolean\n"
1960 "\t\t(\"%s\" /* name */,\n"
1961 "\t\t %s /* nick */,\n"
1962 "\t\t %s /* blurb */,\n"
1963 "\t\t %s /* default_value */,\n"
1965 value_for_print (p->canonical_name, p->name),
1966 value_for_print (p->nick, "NULL"),
1967 value_for_print (p->blurb, "NULL"),
1968 value_for_print (p->default_value, "FALSE"),
1970 } else if (strcmp (p->gtktype, "INT") == 0) {
1971 out_printf (out, "\tparam_spec = g_param_spec_int\n"
1972 "\t\t(\"%s\" /* name */,\n"
1973 "\t\t %s /* nick */,\n"
1974 "\t\t %s /* blurb */,\n"
1975 "\t\t %s /* minimum */,\n"
1976 "\t\t %s /* maximum */,\n"
1977 "\t\t %s /* default_value */,\n"
1979 value_for_print (p->canonical_name, p->name),
1980 value_for_print (p->nick, "NULL"),
1981 value_for_print (p->blurb, "NULL"),
1982 value_for_print (p->minimum, "G_MININT"),
1983 value_for_print (p->maximum, "G_MAXINT"),
1984 value_for_print (p->default_value, "0"),
1986 } else if (strcmp (p->gtktype, "UINT") == 0) {
1987 out_printf (out, "\tparam_spec = g_param_spec_uint\n"
1988 "\t\t(\"%s\" /* name */,\n"
1989 "\t\t %s /* nick */,\n"
1990 "\t\t %s /* blurb */,\n"
1991 "\t\t %s /* minimum */,\n"
1992 "\t\t %s /* maximum */,\n"
1993 "\t\t %s /* default_value */,\n"
1995 value_for_print (p->canonical_name, p->name),
1996 value_for_print (p->nick, "NULL"),
1997 value_for_print (p->blurb, "NULL"),
1998 value_for_print (p->minimum, "0"),
1999 value_for_print (p->maximum, "G_MAXUINT"),
2000 value_for_print (p->default_value, "0"),
2002 } else if (strcmp (p->gtktype, "LONG") == 0) {
2003 out_printf (out, "\tparam_spec = g_param_spec_long\n"
2004 "\t\t(\"%s\" /* name */,\n"
2005 "\t\t %s /* nick */,\n"
2006 "\t\t %s /* blurb */,\n"
2007 "\t\t %s /* minimum */,\n"
2008 "\t\t %s /* maximum */,\n"
2009 "\t\t %s /* default_value */,\n"
2011 value_for_print (p->canonical_name, p->name),
2012 value_for_print (p->nick, "NULL"),
2013 value_for_print (p->blurb, "NULL"),
2014 value_for_print (p->minimum, "G_MINLONG"),
2015 value_for_print (p->maximum, "G_MAXLONG"),
2016 value_for_print (p->default_value, "0"),
2018 } else if (strcmp (p->gtktype, "ULONG") == 0) {
2019 out_printf (out, "\tparam_spec = g_param_spec_ulong\n"
2020 "\t\t(\"%s\" /* name */,\n"
2021 "\t\t %s /* nick */,\n"
2022 "\t\t %s /* blurb */,\n"
2023 "\t\t %s /* minimum */,\n"
2024 "\t\t %s /* maximum */,\n"
2025 "\t\t %s /* default_value */,\n"
2027 value_for_print (p->canonical_name, p->name),
2028 value_for_print (p->nick, "NULL"),
2029 value_for_print (p->blurb, "NULL"),
2030 value_for_print (p->minimum, "0"),
2031 value_for_print (p->maximum, "G_MAXULONG"),
2032 value_for_print (p->default_value, "0"),
2034 } else if (strcmp (p->gtktype, "INT64") == 0) {
2035 out_printf (out, "\tparam_spec = g_param_spec_int64\n"
2036 "\t\t(\"%s\" /* name */,\n"
2037 "\t\t %s /* nick */,\n"
2038 "\t\t %s /* blurb */,\n"
2039 "\t\t %s /* minimum */,\n"
2040 "\t\t %s /* maximum */,\n"
2041 "\t\t %s /* default_value */,\n"
2043 value_for_print (p->canonical_name, p->name),
2044 value_for_print (p->nick, "NULL"),
2045 value_for_print (p->blurb, "NULL"),
2046 value_for_print (p->minimum, "G_MININT64"),
2047 value_for_print (p->maximum, "G_MAXINT64"),
2048 value_for_print (p->default_value, "0"),
2050 } else if (strcmp (p->gtktype, "UINT64") == 0) {
2051 out_printf (out, "\tparam_spec = g_param_spec_uint64\n"
2052 "\t\t(\"%s\" /* name */,\n"
2053 "\t\t %s /* nick */,\n"
2054 "\t\t %s /* blurb */,\n"
2055 "\t\t %s /* minimum */,\n"
2056 "\t\t %s /* maximum */,\n"
2057 "\t\t %s /* default_value */,\n"
2059 value_for_print (p->canonical_name, p->name),
2060 value_for_print (p->nick, "NULL"),
2061 value_for_print (p->blurb, "NULL"),
2062 value_for_print (p->minimum, "0"),
2063 value_for_print (p->maximum, "G_MAXUINT64"),
2064 value_for_print (p->default_value, "0"),
2066 } else if (strcmp (p->gtktype, "UNICHAR") == 0) {
2067 out_printf (out, "\tparam_spec = g_param_spec_unichar\n"
2068 "\t\t(\"%s\" /* name */,\n"
2069 "\t\t %s /* nick */,\n"
2070 "\t\t %s /* blurb */,\n"
2071 "\t\t %s /* default_value */,\n"
2073 value_for_print (p->canonical_name, p->name),
2074 value_for_print (p->nick, "NULL"),
2075 value_for_print (p->blurb, "NULL"),
2076 value_for_print (p->default_value, "0"),
2078 } else if (strcmp (p->gtktype, "ENUM") == 0) {
2079 char *type = make_me_type (p->extra_gtktype,
2081 out_printf (out, "\tparam_spec = g_param_spec_enum\n"
2082 "\t\t(\"%s\" /* name */,\n"
2083 "\t\t %s /* nick */,\n"
2084 "\t\t %s /* blurb */,\n"
2085 "\t\t %s /* enum_type */,\n"
2086 "\t\t %s /* default_value */,\n"
2088 value_for_print (p->canonical_name, p->name),
2089 value_for_print (p->nick, "NULL"),
2090 value_for_print (p->blurb, "NULL"),
2092 value_for_print (p->default_value, "0"),
2095 } else if (strcmp (p->gtktype, "FLAGS") == 0) {
2096 char *type = make_me_type (p->extra_gtktype,
2098 out_printf (out, "\tparam_spec = g_param_spec_flags\n"
2099 "\t\t(\"%s\" /* name */,\n"
2100 "\t\t %s /* nick */,\n"
2101 "\t\t %s /* blurb */,\n"
2102 "\t\t %s /* flags_type */,\n"
2103 "\t\t %s /* default_value */,\n"
2105 value_for_print (p->canonical_name, p->name),
2106 value_for_print (p->nick, "NULL"),
2107 value_for_print (p->blurb, "NULL"),
2109 value_for_print (p->default_value, "0"),
2112 } else if (strcmp (p->gtktype, "FLOAT") == 0) {
2113 out_printf (out, "\tparam_spec = g_param_spec_float\n"
2114 "\t\t(\"%s\" /* name */,\n"
2115 "\t\t %s /* nick */,\n"
2116 "\t\t %s /* blurb */,\n"
2117 "\t\t %s /* minimum */,\n"
2118 "\t\t %s /* maximum */,\n"
2119 "\t\t %s /* default_value */,\n"
2121 value_for_print (p->canonical_name, p->name),
2122 value_for_print (p->nick, "NULL"),
2123 value_for_print (p->blurb, "NULL"),
2124 value_for_print (p->minimum, "-G_MAXFLOAT"),
2125 value_for_print (p->maximum, "G_MAXFLOAT"),
2126 value_for_print (p->default_value, "0.0"),
2128 } else if (strcmp (p->gtktype, "DOUBLE") == 0) {
2129 out_printf (out, "\tparam_spec = g_param_spec_double\n"
2130 "\t\t(\"%s\" /* name */,\n"
2131 "\t\t %s /* nick */,\n"
2132 "\t\t %s /* blurb */,\n"
2133 "\t\t %s /* minimum */,\n"
2134 "\t\t %s /* maximum */,\n"
2135 "\t\t %s /* default_value */,\n"
2137 value_for_print (p->canonical_name, p->name),
2138 value_for_print (p->nick, "NULL"),
2139 value_for_print (p->blurb, "NULL"),
2140 value_for_print (p->minimum, "-G_MAXDOUBLE"),
2141 value_for_print (p->maximum, "G_MAXDOUBLE"),
2142 value_for_print (p->default_value, "0.0"),
2144 } else if (strcmp (p->gtktype, "STRING") == 0) {
2145 out_printf (out, "\tparam_spec = g_param_spec_string\n"
2146 "\t\t(\"%s\" /* name */,\n"
2147 "\t\t %s /* nick */,\n"
2148 "\t\t %s /* blurb */,\n"
2149 "\t\t %s /* default_value */,\n"
2151 value_for_print (p->canonical_name, p->name),
2152 value_for_print (p->nick, "NULL"),
2153 value_for_print (p->blurb, "NULL"),
2154 value_for_print (p->default_value, "NULL"),
2156 } else if (strcmp (p->gtktype, "PARAM") == 0) {
2157 char *type = make_me_type (p->extra_gtktype,
2159 out_printf (out, "\tparam_spec = g_param_spec_param\n"
2160 "\t\t(\"%s\" /* name */,\n"
2161 "\t\t %s /* nick */,\n"
2162 "\t\t %s /* blurb */,\n"
2163 "\t\t %s /* param_type */,\n"
2165 value_for_print (p->canonical_name, p->name),
2166 value_for_print (p->nick, "NULL"),
2167 value_for_print (p->blurb, "NULL"),
2171 } else if (strcmp (p->gtktype, "BOXED") == 0) {
2172 char *type = make_me_type (p->extra_gtktype,
2174 out_printf (out, "\tparam_spec = g_param_spec_boxed\n"
2175 "\t\t(\"%s\" /* name */,\n"
2176 "\t\t %s /* nick */,\n"
2177 "\t\t %s /* blurb */,\n"
2178 "\t\t %s /* boxed_type */,\n"
2180 value_for_print (p->canonical_name, p->name),
2181 value_for_print (p->nick, "NULL"),
2182 value_for_print (p->blurb, "NULL"),
2186 } else if (strcmp (p->gtktype, "POINTER") == 0) {
2187 out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
2188 "\t\t(\"%s\" /* name */,\n"
2189 "\t\t %s /* nick */,\n"
2190 "\t\t %s /* blurb */,\n"
2192 value_for_print (p->canonical_name, p->name),
2193 value_for_print (p->nick, "NULL"),
2194 value_for_print (p->blurb, "NULL"),
2196 /* FIXME: VALUE_ARRAY */
2197 } else if (strcmp (p->gtktype, "CLOSURE") == 0) {
2198 out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
2199 "\t\t(\"%s\" /* name */,\n"
2200 "\t\t %s /* nick */,\n"
2201 "\t\t %s /* blurb */,\n"
2203 value_for_print (p->canonical_name, p->name),
2204 value_for_print (p->nick, "NULL"),
2205 value_for_print (p->blurb, "NULL"),
2207 } else if (strcmp (p->gtktype, "OBJECT") == 0) {
2208 char *type = make_me_type (p->extra_gtktype,
2210 out_printf (out, "\tparam_spec = g_param_spec_object\n"
2211 "\t\t(\"%s\" /* name */,\n"
2212 "\t\t %s /* nick */,\n"
2213 "\t\t %s /* blurb */,\n"
2214 "\t\t %s /* object_type */,\n"
2216 value_for_print (p->canonical_name, p->name),
2217 value_for_print (p->nick, "NULL"),
2218 value_for_print (p->blurb, "NULL"),
2223 error_printf (GOB_ERROR, p->line_no,
2224 "%s type is not supported by properties",
2228 s = g_strdup (p->name);
2230 out_printf (out, "\tg_object_class_install_property (g_object_class,\n"
2232 "\t\tparam_spec);\n", s);
2235 g_string_free (flags, TRUE);
2240 make_arguments(Class *c)
2243 if (get_properties > 0)
2244 out_printf(out, "\tg_object_class->get_property = ___object_get_property;\n");
2245 if (set_properties > 0)
2246 out_printf(out, "\tg_object_class->set_property = ___object_set_property;\n");
2247 out_printf (out, " {\n");
2248 for (li = c->nodes; li != NULL; li = li->next) {
2250 if ((n->type == PROPERTY_NODE && ! ((Property *) n)->override)
2251 || n->type == ARGUMENT_NODE) {
2252 out_printf(out, "\tGParamSpec *param_spec;\n\n");
2257 for (li = c->nodes; li != NULL; li = li->next) {
2259 if (n->type == PROPERTY_NODE)
2260 make_property ((Property *)n);
2261 else if (n->type == ARGUMENT_NODE)
2262 make_argument ((Argument *)n);
2264 out_printf(out, " }\n");
2268 print_initializer(Method *m, Variable *v)
2275 if(v->initializer == NULL)
2278 if(v->scope == PRIVATE_SCOPE)
2279 root = g_strconcat(((FuncArg *)m->args->data)->name,
2282 root = g_strdup(((FuncArg *)m->args->data)->name);
2284 if(v->initializer_line > 0)
2285 out_addline_infile(out, v->initializer_line);
2287 if (v->initializer_simple)
2288 out_printf(out, "\t%s->%s = %s;\n",
2289 root, v->id, v->initializer);
2290 else if (strcmp(v->id, "_glade_xml") == 0)
2291 /* This is OK, this v->initializer string is set internally
2292 and it will eat exactly one string! */
2293 out_printf(out,v->initializer, ((FuncArg *)m->args->data)->name);
2295 out_printf(out, "%s", v->initializer);
2297 if(v->initializer_line > 0)
2298 out_addline_outfile(out);
2304 print_glade_widget(Method *m, Variable *v)
2309 if(!v->glade_widget)
2312 if(v->scope == PRIVATE_SCOPE)
2313 root = g_strconcat(((FuncArg *)m->args->data)->name,
2316 root = g_strdup(((FuncArg *)m->args->data)->name);
2318 cast = get_type(v->vtype, FALSE);
2319 out_printf(out, "\t%s->%s = (%s)glade_xml_get_widget(%s->_glade_xml, \"%s\");\n",
2320 root, v->id, cast, root, v->id);
2326 print_destructor (Variable *v)
2330 if(v->destructor == NULL)
2333 if(v->scope == PRIVATE_SCOPE)
2334 root = "self->_priv";
2338 if(v->destructor_simple) {
2339 if(v->destructor_line > 0)
2340 out_addline_infile(out, v->destructor_line);
2343 out_printf(out, "\tif(%s->%s) { "
2344 "(reinterpret_cast<void (*)(void *)>(%s)) ((gpointer)%s->%s); "
2345 "%s->%s = NULL; }\n",
2346 root, v->id, v->destructor, root, v->id,
2349 out_printf(out, "\tif(%s->%s) { "
2350 "%s ((gpointer) %s->%s); "
2351 "%s->%s = NULL; }\n",
2352 root, v->id, v->destructor, root, v->id,
2356 if(v->destructor_line > 0)
2357 out_addline_outfile(out);
2359 out_printf(out, "#define %s (%s->%s)\n", v->id, root, v->id);
2360 out_printf(out, "#define VAR %s\n", v->id);
2361 out_printf(out, "\t{\n");
2362 if(v->destructor_line > 0)
2363 out_addline_infile(out, v->destructor_line);
2365 out_printf(out, "\t%s}\n", v->destructor);
2367 if(v->destructor_line > 0)
2368 out_addline_outfile(out);
2369 out_printf(out, "\tmemset(&(%s), 0, sizeof(%s));\n",
2371 out_printf(out, "#undef VAR\n");
2372 out_printf(out, "#undef %s\n", v->id);
2377 add_constructor (Class *c)
2379 out_printf(out, "\nstatic GObject *\n"
2380 "___constructor (GType type, guint n_construct_properties, GObjectConstructParam *construct_properties)\n"
2383 "#define __GOB_FUNCTION__ \"%s::constructor\"\n",
2386 out_printf(out, "\tGObject *obj_self;\n");
2387 out_printf(out, "\t%s *self;\n", typebase);
2389 out_printf(out, "\tobj_self = G_OBJECT_CLASS (parent_class)->constructor (type, n_construct_properties, construct_properties);\n");
2390 out_printf(out, "\tself = %s (obj_self);\n", macrobase);
2392 if (user_constructor->line_no > 0)
2393 out_addline_infile (out, user_constructor->line_no);
2394 out_printf (out, "\t%s_constructor (self);\n", funcbase);
2395 if (user_constructor->line_no > 0)
2396 out_addline_outfile (out);
2398 out_printf(out, "\treturn obj_self;\n");
2399 out_printf(out, "}\n"
2400 "#undef __GOB_FUNCTION__\n\n");
2404 print_unreftors (Class *c)
2407 for(li = ((Class *)class)->nodes;
2411 Variable *v = (Variable *)n;
2412 if (n->type == VARIABLE_NODE &&
2413 v->scope != CLASS_SCOPE &&
2414 v->destructor_unref)
2415 print_destructor (v);
2420 add_dispose (Class *c)
2422 out_printf(out, "\nstatic void\n"
2423 "___dispose (GObject *obj_self)\n"
2426 "#define __GOB_FUNCTION__ \"%s::dispose\"\n",
2429 if (unreftors > 0 || user_dispose_method != NULL) {
2430 out_printf (out, "\t%s *self%s = %s (obj_self);\n",
2432 ! no_gnu ? " G_GNUC_UNUSED" : "",
2436 if (dispose_handler != NULL) {
2437 if (unreftors > 0) {
2438 print_unreftors (c);
2441 /* so we get possible bad argument warning */
2442 if (dispose_handler->line_no > 0)
2443 out_addline_infile (out, dispose_handler->line_no);
2444 out_printf (out, "\t___%x_%s_dispose(obj_self);\n",
2445 (guint)dispose_handler->unique_id, funcbase);
2446 if (dispose_handler->line_no > 0)
2447 out_addline_outfile (out);
2449 if (user_dispose_method != NULL) {
2450 if (user_dispose_method->line_no > 0)
2451 out_addline_infile (out, user_dispose_method->line_no);
2452 out_printf (out, "\t%s_dispose (self);\n", funcbase);
2453 if (user_dispose_method->line_no > 0)
2454 out_addline_outfile (out);
2457 if (unreftors > 0) {
2458 print_unreftors (c);
2462 "\tif (G_OBJECT_CLASS (parent_class)->dispose) \\\n"
2463 "\t\t(* G_OBJECT_CLASS (parent_class)->dispose) (obj_self);\n");
2466 out_printf(out, "}\n"
2467 "#undef __GOB_FUNCTION__\n\n");
2471 print_destructors (Class *c)
2474 for (li = ((Class *)class)->nodes;
2478 Variable *v = (Variable *)n;
2479 if (n->type == VARIABLE_NODE &&
2480 v->scope != CLASS_SCOPE &&
2481 ! v->destructor_unref)
2482 print_destructor (v);
2487 add_finalize (Class *c)
2491 "___finalize(GObject *obj_self)\n"
2494 "#define __GOB_FUNCTION__ \"%s::finalize\"\n",
2499 user_finalize_method != NULL) {
2500 const char *unused = "";
2502 unused = " G_GNUC_UNUSED";
2503 out_printf(out, "\t%s *self%s = %s (obj_self);\n",
2504 typebase, unused, macrobase);
2507 const char *unused = "";
2509 unused = " G_GNUC_UNUSED";
2510 out_printf(out, "\tgpointer priv%s = self->_priv;\n",
2514 if(finalize_handler) {
2515 if (destructors > 0) {
2516 print_destructors (c);
2519 /* so we get possible bad argument warning */
2520 if(finalize_handler->line_no > 0)
2521 out_addline_infile(out, finalize_handler->line_no);
2522 out_printf(out, "\t___%x_%s_finalize(obj_self);\n",
2523 (guint)finalize_handler->unique_id, funcbase);
2524 if(finalize_handler->line_no > 0)
2525 out_addline_outfile(out);
2527 if (user_finalize_method != NULL) {
2528 if (user_finalize_method->line_no > 0)
2529 out_addline_infile (out, user_finalize_method->line_no);
2530 out_printf (out, "\t%s_finalize (self);\n", funcbase);
2531 if (user_finalize_method->line_no > 0)
2532 out_addline_outfile (out);
2535 if (destructors > 0) {
2536 print_destructors (c);
2540 "\tif(G_OBJECT_CLASS(parent_class)->finalize) \\\n"
2541 "\t\t(* G_OBJECT_CLASS(parent_class)->finalize)(obj_self);\n");
2544 out_printf(out, "}\n"
2545 "#undef __GOB_FUNCTION__\n\n");
2549 make_bonobo_object_epv (Class *c, const char *classname)
2552 gboolean added_line = FALSE;
2554 for (li = c->nodes; li != NULL; li = li->next) {
2556 Method *m = (Method *)n;
2557 if(n->type != METHOD_NODE ||
2558 m->method == OVERRIDE_METHOD)
2561 if (m->bonobo_object_func) {
2562 if(m->line_no > 0) {
2563 out_addline_infile(out, m->line_no);
2565 } else if (m->line_no == 0 &&
2567 out_addline_outfile(out);
2570 out_printf (out, "\t%s->_epv.%s = self_%s;\n",
2571 classname, m->id, m->id);
2575 out_addline_outfile(out);
2578 static void add_class_private(Class *c, Method *m)
2580 const char *dynamic = c->dynamic ? "_DYNAMIC" : "";
2585 out_printf(out, "\n#if !defined(G_DEFINE%s_TYPE_EXTENDED)"
2586 " || !defined(G_ADD_PRIVATE%s)\n"
2587 "\tg_type_class_add_private(%s, sizeof(%sPrivate));\n"
2590 ((FuncArg *)m->args->data)->name, typebase);
2593 static void get_instance_private(Class *c, Method *m)
2595 const char *self = ((FuncArg *)m->args->data)->name;
2596 const char *dynamic = c->dynamic ? "_DYNAMIC" : "";
2599 if (always_private_struct) {
2600 out_printf(out, "\t%s->_priv = NULL;\n", self);
2606 out_printf(out, "\t%s->_priv = (%sPrivate *)\n"
2607 "#if defined(G_DEFINE%s_TYPE_EXTENDED)"
2608 " && defined(G_ADD_PRIVATE%s)\n"
2609 "\t\t%s_get_instance_private(%s);\n"
2611 "\t\tG_TYPE_INSTANCE_GET_PRIVATE\n"
2614 "\t\t\t, %sPrivate\n"
2620 self, macrotype, typebase);
2626 const char *unused = "";
2630 unused = " G_GNUC_UNUSED";
2632 for(li=c->nodes;li;li=g_list_next(li)) {
2636 if(n->type != METHOD_NODE)
2639 if(m->method == INIT_METHOD) {
2641 out_addline_infile(out, m->line_no);
2642 print_method(out, "static ", "\n", "", " ", "", "\n",
2643 m, FALSE, FALSE, FALSE, TRUE, TRUE,
2645 out_printf(out, "{\n");
2647 out_addline_outfile(out);
2649 "#define __GOB_FUNCTION__ \"%s::init\"\n",
2652 get_instance_private(c, m);
2654 if(initializers > 0) {
2656 for(li = ((Class *)class)->nodes;
2660 Variable *v = (Variable *)n;
2661 if(n->type != VARIABLE_NODE ||
2662 v->scope == CLASS_SCOPE)
2664 print_initializer(m, v);
2667 if(glade_widgets > 0) {
2669 for(li = ((Class *)class)->nodes;
2673 Variable *v = (Variable *)n;
2674 if(n->type != VARIABLE_NODE ||
2675 v->scope == CLASS_SCOPE)
2677 print_glade_widget(m, v);
2680 } else if(m->method == CLASS_INIT_METHOD) {
2681 gboolean did_base_obj = FALSE;
2684 out_addline_infile(out, m->line_no);
2685 print_method(out, "static ", "\n", "", " ", "", "\n",
2686 m, FALSE, FALSE, FALSE, TRUE, TRUE,
2688 out_printf(out, "{\n");
2690 out_addline_outfile(out);
2692 "#define __GOB_FUNCTION__ \"%s::class_init\"\n",
2694 if (set_properties > 0 ||
2695 get_properties > 0 ||
2702 "g_object_class%s = "
2703 "(GObjectClass*) %s;\n",
2705 ((FuncArg *)m->args->data)->name);
2706 did_base_obj = TRUE;
2711 ((FuncArg *)m->args->data)->name,
2714 add_class_private(c, m);
2716 if (initializers > 0) {
2718 for(li = ((Class *)class)->nodes;
2722 Variable *v = (Variable *)n;
2723 if(n->type == VARIABLE_NODE &&
2724 v->scope == CLASS_SCOPE)
2725 print_initializer(m, v);
2729 out_printf(out, "\n\tparent_class = ");
2731 out_printf(out, "(%sClass *)", ptypebase);
2732 out_printf(out, "g_type_class_ref (%s);\n",
2738 set_def_handlers(c, ((FuncArg *)m->args->data)->name);
2740 /* if there are no handlers for these things, we
2741 * need to set them up here */
2742 if(need_constructor)
2743 out_printf(out, "\tg_object_class->constructor "
2744 "= ___constructor;\n");
2745 if(need_dispose && !dispose_handler)
2746 out_printf(out, "\tg_object_class->dispose "
2748 if(need_finalize && !finalize_handler)
2749 out_printf(out, "\tg_object_class->finalize = "
2752 if(get_properties > 0 || set_properties > 0)
2755 if (c->bonobo_object_class != NULL) {
2756 make_bonobo_object_epv (c, ((FuncArg *)m->args->data)->name);
2762 out_printf(out, " {\n");
2763 out_addline_infile(out, m->ccode_line);
2764 out_printf(out, "%s\n", m->cbuf);
2765 out_addline_outfile(out);
2766 out_printf(out, " }\n");
2768 out_printf(out, "}\n"
2769 "#undef __GOB_FUNCTION__\n");
2774 add_argument (Argument *a, gboolean is_set)
2778 char *the_type_lower;
2783 line_no = a->set_line;
2786 line_no = a->get_line;
2790 s = g_strdup(a->name);
2792 out_printf(out, "\tcase PROP_%s:\n\t{", s);
2794 the_type_lower = g_strdup (a->gtktype);
2795 gob_strdown (the_type_lower);
2797 /* HACK because there is no g_value_set/get for unichar */
2798 if (strcmp (the_type_lower, "unichar") == 0) {
2799 g_free (the_type_lower);
2800 the_type_lower = g_strdup ("uint");
2805 const char *unused = "";
2807 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
2808 unused = " G_GNUC_UNUSED";
2811 if (a->atype != NULL &&
2812 /* gcc -Wbad-function-cast is wanking stupid, moronic
2813 and otherwise evil so we should just use a (gint)
2814 or (guint) cast, not the specific type cast */
2816 (strcmp (a->gtktype, "ENUM") != 0 &&
2817 strcmp (a->gtktype, "FLAGS") != 0)))
2818 cast = get_type (a->atype, TRUE);
2820 cast = g_strdup (get_cast (a->gtktype, FALSE));
2822 out_printf (out, "\t%s ARG%s = (%s) g_value_get_%s (VAL);\n",
2823 cast, unused, cast, the_type_lower);
2826 } else if ( ! is_set) {
2829 if (a->atype != NULL)
2830 cast = get_type (a->atype, TRUE);
2832 cast = g_strdup (get_cast (a->gtktype, FALSE));
2833 out_printf (out, "\t%s ARG;\n"
2834 "\tmemset (&ARG, 0, sizeof (%s));\n",
2840 out_printf(out, "\t\t{\n");
2842 out_addline_infile (out, line_no);
2843 out_printf (out, "%s\n", cbuf);
2845 out_addline_outfile (out);
2846 out_printf (out, "\t\t}\n");
2848 if (strcmp (a->gtktype, "OBJECT") == 0)
2849 out_printf (out, "\t\tg_value_set_%s (VAL, G_OBJECT (ARG));\n",
2852 out_printf (out, "\t\t"
2853 "g_value_set_%s (VAL, ARG);\n",
2856 g_free (the_type_lower);
2859 (no_gnu || for_cpp /* g++ has a cow with G_GNUC_UNUSED */)) {
2860 out_printf (out, "\t\tif (&ARG) break;\n");
2863 out_printf (out, "\t\tbreak;\n");
2865 out_printf (out, "\t}\n");
2869 add_property (Property *p, gboolean is_set)
2872 char *the_type_lower;
2878 line_no = p->set_line;
2881 line_no = p->get_line;
2886 name_upper = g_strdup (p->name);
2887 gob_strup (name_upper);
2888 the_type_lower = g_strdup (p->gtktype);
2889 gob_strdown (the_type_lower);
2891 out_printf (out, "\tcase PROP_%s:\n", name_upper);
2893 out_printf(out, "\t\t{\n");
2895 out_addline_infile (out, line_no);
2896 out_printf (out, "%s\n", cbuf);
2898 out_addline_outfile (out);
2899 out_printf (out, "\t\t}\n");
2901 g_free (name_upper);
2902 g_free (the_type_lower);
2904 out_printf (out, "\t\tbreak;\n");
2908 add_getset_arg(Class *c, gboolean is_set)
2911 const char *unused = "";
2912 const char *hack_unused = "";
2914 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
2915 unused = " G_GNUC_UNUSED";
2917 hack_unused = "if (&VAL || &pspec) break;\n\t\t";
2920 out_printf(out, "\nstatic void\n"
2921 "___object_%s_property (GObject *object,\n"
2922 "\tguint property_id,\n"
2923 "\t%sGValue *VAL%s,\n"
2924 "\tGParamSpec *pspec%s)\n"
2925 "#define __GOB_FUNCTION__ \"%s::%s_property\"\n"
2928 "\tself = %s (object);\n\n"
2929 "\tswitch (property_id) {\n",
2930 is_set ? "set" : "get",
2931 is_set ? "const " : "",
2935 is_set ? "set" : "get",
2940 for (li = c->nodes; li != NULL; li = li->next) {
2942 if (n->type == PROPERTY_NODE)
2943 add_property ((Property *)n, is_set);
2944 else if (n->type == ARGUMENT_NODE)
2945 add_argument ((Argument *)n, is_set);
2947 out_printf (out, "\tdefault:\n"
2948 "/* Apparently in g++ this is needed, glib is b0rk */\n"
2949 "#ifndef __PRETTY_FUNCTION__\n"
2950 "# undef G_STRLOC\n"
2951 "# define G_STRLOC __FILE__ \":\" G_STRINGIFY (__LINE__)\n"
2953 "\t\tG_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);\n"
2954 "\t\t%sbreak;\n\t}\n"
2956 "#undef __GOB_FUNCTION__\n", hack_unused);
2960 print_checks (Method *m, FuncArg *fa)
2964 gboolean checked_null = FALSE;
2965 is_void = (strcmp(m->mtype->name, "void")==0 &&
2966 m->mtype->pointer == NULL);
2968 for(li = fa->checks; li != NULL; li = li->next) {
2969 Check *ch = li->data;
2971 /* point to the method prot in .gob for failed checks */
2973 out_addline_infile(out, m->line_no);
2975 out_printf(out, "\tg_return_if_fail (");
2977 out_printf(out, "\tg_return_val_if_fail (");
2978 switch(ch->chtype) {
2980 out_printf(out, "%s != NULL", fa->name);
2981 checked_null = TRUE;
2984 s = make_pre_macro(fa->atype->name, "IS");
2986 out_printf(out, "%s (%s)", s, fa->name);
2988 /* if not check null, null may be valid */
2989 out_printf(out, "!(%s) || %s (%s)", fa->name,
2994 out_printf(out, "%s < %s", fa->name, ch->number);
2997 out_printf(out, "%s > %s", fa->name, ch->number);
3000 out_printf(out, "%s <= %s", fa->name, ch->number);
3003 out_printf(out, "%s >= %s", fa->name, ch->number);
3006 out_printf(out, "%s == %s", fa->name, ch->number);
3009 out_printf(out, "%s != %s", fa->name, ch->number);
3013 out_printf(out, ");\n");
3015 out_printf(out, ", (");
3016 print_type(out, m->mtype, TRUE);
3017 out_printf(out, ")%s);\n",
3018 m->onerror?m->onerror:"0");
3024 print_preconditions(Method *m)
3028 for(li=m->args;li;li=g_list_next(li)) {
3029 FuncArg *fa = li->data;
3031 print_checks(m, fa);
3034 out_addline_outfile(out);
3038 print_method_body (Method *m, gboolean pre, gboolean unused_self)
3040 out_printf(out, "{\n");
3042 out_addline_outfile(out);
3043 out_printf(out, "#define __GOB_FUNCTION__ \"%s::%s\"\n",
3044 ((Class *)class)->otype,
3047 print_preconditions(m);
3051 (no_gnu || for_cpp) &&
3053 ((FuncArg *)(m->args->data))->name != NULL &&
3054 strcmp (((FuncArg *)(m->args->data))->name, "self") == 0) {
3055 out_printf (out, "\tif (&self) { ; }\n");
3058 /* Note: the trailing }'s are on one line, this is so
3059 that we get the no return warning correctly and point to
3060 the correct line in the .gob file, yes this is slightly
3061 ugly in the .c file, but that is not supposed to be
3062 human readable anyway. */
3064 out_printf(out, "{\n");
3066 out_addline_infile(out, m->ccode_line);
3067 out_printf(out, "\t%s}", m->cbuf);
3070 /* Note, there is no \n between the last } and this } so that
3071 * errors/warnings reported on the end of the body get pointed to the
3072 * right line in the .gob source */
3073 out_printf(out, "}\n");
3076 out_addline_outfile(out);
3077 out_printf(out, "#undef __GOB_FUNCTION__\n");
3081 put_signal_args (Method *m)
3087 if (m->args->next == NULL)
3090 for (ali = m->gtktypes->next, li = m->args->next, i = 1;
3091 li != NULL && ali != NULL;
3092 li = li->next, ali = ali->next, i++) {
3093 FuncArg *fa = li->data;
3094 char *str = ali->data;
3095 char *cast = g_strdup (get_cast (str, FALSE));
3096 /* FIXME: This code is so fucking ugly it hurts */
3097 gboolean do_static =
3098 (strcmp (str, "STRING") == 0 ||
3099 strcmp (str, "BOXED") == 0 ||
3100 strncmp (str, "BOXED_", 6) == 0);
3105 cast = get_type (fa->atype, TRUE);
3107 /* we should have already proved before that
3108 the we know all the types */
3109 g_assert (cast != NULL);
3111 if (strncmp (str, "BOXED_", 6) == 0)
3112 t = g_strdup (&(str[6]));
3114 t = g_strconcat ("G_TYPE_", str, NULL);
3117 "\t___param_values[%d].g_type = 0;\n"
3118 "\tg_value_init (&___param_values[%d], %s);\n",
3122 if (strcmp (str, "UNICHAR") == 0)
3123 /* hack because glib is braindamaged */
3124 set_func = g_strdup ("g_value_set_uint");
3125 else if (strncmp (str, "BOXED_", 6) == 0)
3126 set_func = g_strdup ("g_value_set_static_boxed");
3128 set_func = g_strdup_printf ("g_value_set%s_%s",
3129 do_static ? "_static" : "",
3131 gob_strdown (set_func);
3133 out_printf (out, "\t%s (&___param_values[%d], (%s) %s);\n\n",
3134 set_func, i, cast, fa->name);
3142 clear_signal_args (Method *m)
3147 out_printf (out, "\n\tg_value_unset (&___param_values[0]);\n");
3149 if (m->args->next == NULL)
3152 for (li = m->args->next, i = 1;
3154 li = li->next, i++) {
3156 "\tg_value_unset (&___param_values[%d]);\n", i);
3161 get_arg_names_for_macro (Method *m)
3166 GString *gs = g_string_new(NULL);
3168 for(li=m->args;li;li=g_list_next(li)) {
3169 FuncArg *arg = li->data;
3170 g_string_append_printf(gs, "%s___%s", sep, arg->name);
3175 g_string_free(gs, FALSE);
3179 static gboolean method_is_void(Method *m)
3181 return !strcmp(m->mtype->name, "void") && !m->mtype->pointer;
3184 static const char *method_err_retval(Method *m)
3186 if (method_is_void(m))
3194 put_interface_parent_handler(Method *m)
3196 const char *errval = method_err_retval(m);
3197 char *name = replace_sep(m->interface, '_');
3198 char *args = get_arg_names_for_macro(m);
3200 out_printf(out, "#define PARENT_HANDLER(%s) (%s_parent_iface \\\n"
3201 "\t? %s_parent_iface->%s(%s) \\\n"
3202 "\t: %s)\n", args, name, name, m->id, args, errval);
3209 put_method(Method *m)
3211 char *s, *args, *doc;
3213 is_void = (strcmp(m->mtype->name, "void")==0 &&
3214 m->mtype->pointer == NULL);
3215 out_printf(out, "\n");
3216 if(m->method != OVERRIDE_METHOD) {
3217 doc = get_gtk_doc(m->id);
3219 out_printf(out, "%s", doc);
3225 case REGULAR_METHOD:
3227 out_addline_infile(out, m->line_no);
3228 if(m->scope == PRIVATE_SCOPE)
3229 print_method(out, "static ", "\n", "", " ", "", "\n",
3230 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3231 else /* PUBLIC, PROTECTED */
3232 print_method(out, "", "\n", "", " ", "", "\n",
3233 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3236 out_addline_outfile(out);
3237 put_interface_parent_handler(m);
3240 print_method_body(m, TRUE, TRUE);
3243 out_printf(out, "#undef PARENT_HANDLER\n");
3246 /* the outfile line was added above */
3248 case SIGNAL_FIRST_METHOD:
3249 case SIGNAL_LAST_METHOD:
3251 out_addline_infile(out, m->line_no);
3252 if(m->scope == PRIVATE_SCOPE)
3253 print_method(out, "static ", "\n", "", " ", "", "\n",
3254 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3255 else /* PUBLIC, PROTECTED */
3256 print_method(out, "", "\n", "", " ", "", "\n",
3257 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3258 out_printf (out, "{\n");
3260 out_addline_outfile (out);
3263 "\tGValue ___param_values[%d];\n"
3264 "\tGValue ___return_val;\n\n"
3265 "memset (&___return_val, 0, "
3266 "sizeof (___return_val));\n"
3267 "memset (&___param_values, 0, "
3268 "sizeof (___param_values));\n\n",
3269 g_list_length (m->args));
3271 print_preconditions (m);
3274 "\n\t___param_values[0].g_type = 0;\n"
3275 "\tg_value_init (&___param_values[0], G_TYPE_FROM_INSTANCE (%s));\n"
3276 "\tg_value_set_instance (&___param_values[0], (gpointer) %s);\n\n",
3277 ((FuncArg *)m->args->data)->name,
3278 ((FuncArg *)m->args->data)->name);
3280 put_signal_args (m);
3282 if (strcmp (m->gtktypes->data, "NONE") != 0) {
3283 const char *defret = NULL;
3285 out_printf (out, "\tg_value_init (&___return_val, G_TYPE_%s);\n",
3286 (char *)m->gtktypes->data);
3288 if (m->defreturn != NULL)
3289 defret = m->defreturn;
3290 else if (m->onerror != NULL)
3291 defret = m->onerror;
3293 if (defret != NULL) {
3295 /* FIXME: This code is so fucking ugly it hurts */
3296 gboolean do_static =
3297 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
3298 strcmp ((char *)m->gtktypes->data, "BOXED") == 0);
3299 char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
3301 cast = get_type (m->mtype, TRUE);
3303 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
3304 /* hack because glib is braindamaged */
3305 set_func = g_strdup ("g_value_set_uint");
3307 set_func = g_strdup_printf ("g_value_set%s_%s",
3308 do_static ? "_static" : "",
3309 (char *)m->gtktypes->data);
3310 gob_strdown (set_func);
3312 out_printf (out, "\t%s (&___return_val, (%s) (%s));\n",
3313 set_func, cast, defret);
3318 out_printf (out, "\n");
3321 s = g_strdup (m->id);
3324 out_printf(out, "\tg_signal_emitv (___param_values,\n"
3325 "\t\tobject_signals[%s_SIGNAL],\n"
3326 "\t\t0 /* detail */,\n"
3327 "\t\t&___return_val);\n", s);
3331 clear_signal_args (m);
3333 if (strcmp (m->gtktypes->data, "NONE") != 0) {
3334 char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
3336 /* Hack because glib is very very braindead */
3338 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
3339 strcmp ((char *)m->gtktypes->data, "BOXED") == 0 ||
3340 strcmp ((char *)m->gtktypes->data, "OBJECT") == 0 ||
3341 strcmp ((char *)m->gtktypes->data, "PARAM") == 0);
3343 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
3344 /* hack because glib is braindamaged */
3345 getfunc = g_strdup ("g_value_get_uint");
3347 getfunc = g_strdup_printf ("g_value_%s_%s",
3348 do_dup ? "dup" : "get",
3349 (char *)m->gtktypes->data);
3350 gob_strdown (getfunc);
3353 cast = get_type (m->mtype, TRUE);
3358 print_type (out, m->mtype, TRUE);
3360 " ___ret = (%s) %s (&___return_val);\n"
3361 "\t\tg_value_unset (&___return_val);\n"
3362 "\t\treturn ___ret;\n"
3369 out_printf(out, "}\n");
3374 out_addline_infile(out, m->line_no);
3375 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
3376 m, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE);
3377 print_method_body(m, FALSE, TRUE);
3378 /* the outfile line was added above */
3380 case VIRTUAL_METHOD:
3382 out_addline_infile(out, m->line_no);
3383 if(m->scope==PRIVATE_SCOPE)
3384 print_method(out, "static ", "\n", "", " ", "", "\n",
3385 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3386 else /* PUBLIC, PROTECTED */
3387 print_method(out, "", "\n", "", " ", "", "\n",
3388 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3389 out_printf(out, "{\n");
3390 out_addline_outfile(out);
3391 out_printf(out, "\t%sClass *klass;\n", typebase);
3392 print_preconditions(m);
3393 out_printf(out, "\tklass = %s_GET_CLASS(%s);\n\n"
3394 "\tif(klass->%s)\n",
3395 macrobase, ((FuncArg *)m->args->data)->name,
3397 if(strcmp(m->mtype->name, "void") == 0 &&
3398 m->mtype->pointer == NULL) {
3400 out_printf(out, "\t\t(*klass->%s)(%s",
3402 ((FuncArg *)m->args->data)->name);
3403 for(li=m->args->next;li;li=g_list_next(li)) {
3404 FuncArg *fa = li->data;
3405 out_printf(out, ",%s", fa->name);
3407 out_printf(out, ");\n}\n");
3410 out_printf(out, "\t\treturn (*klass->%s)(%s",
3412 ((FuncArg *)m->args->data)->name);
3413 for(li=m->args->next;li;li=g_list_next(li)) {
3414 FuncArg *fa = li->data;
3415 out_printf(out, ",%s", fa->name);
3417 out_printf(out, ");\n"
3420 print_type(out, m->mtype, TRUE);
3422 out_printf(out, ")(%s);\n}\n", m->defreturn);
3424 out_printf(out, ")(%s);\n}\n", m->onerror);
3426 out_printf(out, ")(0);\n}\n");
3432 out_addline_infile(out, m->line_no);
3433 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
3434 m, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE);
3435 print_method_body(m, FALSE, TRUE);
3436 /* the outfile line was added above */
3438 case OVERRIDE_METHOD:
3442 out_addline_infile(out, m->line_no);
3443 s = g_strdup_printf("\n___%x_", (guint)m->unique_id);
3444 print_method(out, "static ", s, "", " ", "", "\n",
3445 m, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE);
3447 out_addline_outfile(out);
3448 s = replace_sep(m->otype, '_');
3450 args = get_arg_names_for_macro(m);
3452 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
3453 "\t{ if(%s_CLASS(parent_class)->%s) \\\n"
3454 "\t\t(* %s_CLASS(parent_class)->%s)(%s); }\n",
3455 args, s, m->id, s, m->id, args);
3457 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
3458 "\t((%s_CLASS(parent_class)->%s)? \\\n"
3459 "\t\t(* %s_CLASS(parent_class)->%s)(%s): \\\n"
3461 args, s, m->id, s, m->id, args);
3462 out_printf(out, "(");
3463 print_type(out, m->mtype, TRUE);
3464 out_printf(out, ")%s))\n",
3465 m->onerror?m->onerror:"0");
3469 print_method_body(m, TRUE, TRUE);
3470 /* the outfile line was added above */
3471 out_printf(out, "#undef PARENT_HANDLER\n");
3473 case CONSTRUCTOR_METHOD:
3474 case DISPOSE_METHOD:
3475 case FINALIZE_METHOD:
3477 out_addline_infile(out, m->line_no);
3478 print_method(out, "static ", "\n", "", " ", "", "\n",
3479 m, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE);
3480 print_method_body(m, TRUE, TRUE);
3481 /* the outfile line was added above */
3490 char *outfile, *outfileh, *outfileph;
3492 outfilebase = g_strconcat (fullfilebase, for_cpp ? ".cc" : ".c", NULL);
3493 outfile = g_strconcat(outfilebase, no_touch ? "#gob#" : "", NULL);
3495 outfilehbase = g_strconcat (fullfilebase, ".h", NULL);
3496 outfileh = g_strconcat(outfilehbase, no_touch_headers ? "#gob#" : "", NULL);
3498 if ((privates > 0 || protecteds > 0 ||
3499 private_header == PRIVATE_HEADER_ALWAYS) &&
3500 private_header != PRIVATE_HEADER_NEVER) {
3501 char sep[2] = {0,0};
3504 outfilephbase = g_strconcat (fullfilebase, sep, "private.h", NULL);
3505 outfileph = g_strconcat (outfilephbase, no_touch_headers ? "#gob#" : "", NULL);
3507 outfilephbase = NULL;
3513 out = fopen (outfile, "w");
3515 error_printf (GOB_ERROR, 0,
3516 "Cannot open outfile: %s", outfile);
3518 outh = fopen (outfileh, "w");
3520 error_printf (GOB_ERROR, 0,
3521 "Cannot open outfile: %s", outfileh);
3523 if (outfileph != NULL) {
3524 outph = fopen (outfileph, "w");
3525 if (outph == NULL) {
3526 error_printf (GOB_ERROR, 0,
3527 "Cannot open outfile: %s",
3535 put_argument_nongnu_wrappers (Class *c)
3539 if (get_properties < 0 && set_properties < 0)
3542 for (li = c->nodes; li != NULL; li = li->next) {
3544 const char *name, *gtktype;
3550 if (n->type == ARGUMENT_NODE) {
3551 Argument *a = (Argument *)n;
3553 gtktype = a->gtktype;
3555 get = a->get != NULL;
3556 set = a->set != NULL;
3557 } else if (n->type == PROPERTY_NODE) {
3558 Property *p = (Property *)n;
3560 gtktype = p->gtktype;
3562 get = p->get != NULL;
3563 set = p->set != NULL;
3568 aname = g_strdup (name);
3572 cast = get_type (atype, TRUE);
3574 cast = g_strdup (get_cast (gtktype, TRUE));
3578 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3579 "\"%s\",(%s)(arg)\n",
3580 macrobase, aname, name, cast);
3582 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3583 "\"%s\",(%s*)(arg)\n",
3584 macrobase, aname, name, cast);
3587 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3589 macrobase, aname, name);
3591 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3593 macrobase, aname, name);
3601 put_argument_gnu_wrappers(Class *c)
3605 if(get_properties < 0 && set_properties < 0)
3608 for (li = c->nodes; li != NULL; li = li->next) {
3610 const char *name, *gtktype;
3616 if (n->type == ARGUMENT_NODE) {
3617 Argument *a = (Argument *)n;
3619 gtktype = a->gtktype;
3621 get = a->get != NULL;
3622 set = a->set != NULL;
3623 } else if (n->type == PROPERTY_NODE) {
3624 Property *p = (Property *)n;
3626 gtktype = p->gtktype;
3628 get = p->get != NULL;
3629 set = p->set != NULL;
3634 aname = g_strdup (name);
3638 cast = get_type (atype, TRUE);
3640 cast = g_strdup (get_cast (gtktype, TRUE));
3644 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3645 "\"%s\", __extension__ ({%sz = (arg); z;})\n",
3646 macrobase, aname, name, cast);
3648 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3649 "\"%s\", __extension__ ({%s*z = (arg); z;})\n",
3650 macrobase, aname, name, cast);
3653 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3655 macrobase, aname, name);
3657 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3659 macrobase, aname, name);
3667 print_ccode_block(CCode *cc)
3670 switch(cc->cctype) {
3672 /* HT code is printed exactly like normal header
3673 code but is printed before */
3676 out_printf(fp, "\n");
3679 /* AT code is printed exactly like normal 'all'
3680 code but is printed before */
3683 out_printf(outph, "\n");
3684 out_printf(outph, "%s\n", cc->cbuf);
3685 out_addline_infile(outph, cc->line_no);
3686 out_addline_outfile(outph);
3688 out_printf(outh, "\n");
3689 out_printf(outh, "%s\n", cc->cbuf);
3691 out_printf(fp, "\n");
3692 out_addline_infile(fp, cc->line_no);
3698 out_printf(fp, "\n");
3699 out_addline_infile(fp, cc->line_no);
3706 out_printf(fp, "\n");
3707 out_addline_infile(fp, cc->line_no);
3710 out_printf(fp, "%s\n", cc->cbuf);
3711 if(cc->cctype == C_CCODE ||
3712 cc->cctype == AD_CCODE ||
3713 cc->cctype == A_CCODE ||
3714 cc->cctype == AT_CCODE ||
3715 cc->cctype == PH_CCODE)
3716 out_addline_outfile(fp);
3720 print_class_block(Class *c)
3724 gboolean printed_private = FALSE;
3728 out_printf(outph ? outph : outh, "#include <gtk/gtk.h>\n");
3729 out_printf(outph ? outph : outh, "#include <glade/glade-xml.h>\n\n");
3733 out_printf(out, "/* utility types we may need */\n");
3734 if(special_array[SPECIAL_2POINTER])
3735 out_printf(out, "typedef struct { "
3736 "gpointer a; gpointer b; "
3737 "} ___twopointertype;\n");
3738 if(special_array[SPECIAL_3POINTER])
3739 out_printf(out, "typedef struct { "
3740 "gpointer a; gpointer b; "
3742 "} ___threepointertype;\n");
3743 if(special_array[SPECIAL_INT_POINTER])
3744 out_printf(out, "typedef struct { "
3745 "gint a; gpointer b; "
3746 "} ___intpointertype;\n");
3747 out_printf(out, "\n");
3750 out_printf(outh, "\n/*\n"
3751 " * Type checking and casting macros\n"
3753 out_printf(outh, "#define %s\t"
3754 "(%s_get_type())\n",
3755 macrotype, funcbase);
3756 out_printf(outh, "#define %s(obj)\t"
3757 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s)\n",
3758 macrobase, funcbase, typebase);
3759 out_printf(outh, "#define %s_CONST(obj)\t"
3760 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s const)\n",
3761 macrobase, funcbase, typebase);
3762 out_printf(outh, "#define %s_CLASS(klass)\t"
3763 "G_TYPE_CHECK_CLASS_CAST((klass), %s_get_type(), %sClass)\n",
3764 macrobase, funcbase, typebase);
3765 out_printf(outh, "#define %s(obj)\t"
3766 "G_TYPE_CHECK_INSTANCE_TYPE((obj), %s_get_type ())\n\n",
3769 "#define %s_GET_CLASS(obj)\t"
3770 "G_TYPE_INSTANCE_GET_CLASS((obj), %s_get_type(), %sClass)\n",
3771 macrobase, funcbase, typebase);
3773 if ( ! no_self_alias) {
3774 out_printf(out, "/* self casting macros */\n");
3775 out_printf(out, "#define SELF(x) %s(x)\n", macrobase);
3776 out_printf(out, "#define SELF_CONST(x) %s_CONST(x)\n", macrobase);
3777 out_printf(out, "#define IS_SELF(x) %s(x)\n", macrois);
3778 out_printf(out, "#define TYPE_SELF %s\n", macrotype);
3779 out_printf(out, "#define SELF_CLASS(x) %s_CLASS(x)\n\n",
3781 out_printf(out, "#define SELF_GET_CLASS(x) %s_GET_CLASS(x)\n\n",
3784 out_printf(out, "/* self typedefs */\n");
3785 out_printf(out, "typedef %s Self;\n", typebase);
3786 out_printf(out, "typedef %sClass SelfClass;\n\n", typebase);
3790 always_private_struct) {
3791 out_printf (outh, "\n/* Private structure type */\n");
3792 out_printf (outh, "typedef struct _%sPrivate %sPrivate;\n",
3793 typebase, typebase);
3795 out_printf (outh, "/* There are no privates, this "
3796 "structure is thus never defined */\n");
3799 out_printf (outh, "\n/*\n"
3800 " * Main object structure\n"
3802 s = replace_sep (c->otype, '_');
3804 out_printf (outh, "#ifndef __TYPEDEF_%s__\n"
3805 "#define __TYPEDEF_%s__\n", s, s);
3807 out_printf (outh, "typedef struct _%s %s;\n"
3808 "#endif\n", typebase, typebase);
3809 out_printf (outh, "struct _%s {\n\t%s __parent__;\n",
3810 typebase, ptypebase);
3811 for (li = c->nodes; li; li=li->next) {
3812 static gboolean printed_public = FALSE;
3814 Variable *v = (Variable *)n;
3815 if(n->type == VARIABLE_NODE &&
3816 v->scope == PUBLIC_SCOPE) {
3817 if( ! printed_public) {
3818 out_printf(outh, "\t/*< public >*/\n");
3819 printed_public = TRUE;
3821 put_variable((Variable *)n, outh);
3824 /* put protecteds always AFTER publics */
3825 for (li = c->nodes; li != NULL; li = li->next) {
3827 Variable *v = (Variable *)n;
3828 if (n->type == VARIABLE_NODE &&
3829 v->scope == PROTECTED_SCOPE) {
3830 if ( ! printed_private) {
3831 out_printf (outh, "\t/*< private >*/\n");
3832 printed_private = TRUE;
3834 put_variable ((Variable *)n, outh);
3838 always_private_struct) {
3839 if ( ! printed_private)
3840 out_printf (outh, "\t/*< private >*/\n");
3841 out_printf (outh, "\t%sPrivate *_priv;\n", typebase);
3843 out_printf (outh, "};\n");
3848 /* if we are to stick this into the private
3849 header, if not stick it directly into the
3856 out_printf (outfp, "struct _%sPrivate {\n",
3860 for(li=c->nodes; li; li=li->next) {
3862 Variable *v = (Variable *)n;
3863 if(n->type == VARIABLE_NODE &&
3864 v->scope == PRIVATE_SCOPE) {
3865 out_addline_infile(outfp, v->line_no);
3866 put_variable(v, outfp);
3869 out_addline_outfile(outfp);
3871 out_printf(outfp, "};\n");
3874 out_printf(outh, "\n/*\n"
3875 " * Class definition\n"
3877 out_printf(outh, "typedef struct _%sClass %sClass;\n",
3878 typebase, typebase);
3880 "struct _%sClass {\n\t%sClass __parent__;\n",
3881 typebase, ptypebase);
3882 for(li = c->nodes; li != NULL; li = li->next) {
3884 if(n->type == METHOD_NODE)
3885 put_vs_method((Method *)n);
3887 /* If BonoboX type class put down the epv */
3888 if (c->bonobo_object_class != NULL) {
3890 "\t/* Bonobo object epv */\n"
3891 "\tPOA_%s__epv _epv;\n",
3892 c->bonobo_object_class);
3894 /* put class scope variables */
3895 for (li = c->nodes; li != NULL; li = li->next) {
3897 Variable *v = (Variable *)n;
3898 if (n->type == VARIABLE_NODE &&
3899 v->scope == CLASS_SCOPE)
3900 put_variable ((Variable *)n, outh);
3902 out_printf (outh, "};\n\n");
3904 out_printf (out, "/* here are local prototypes */\n");
3905 if (set_properties > 0) {
3906 out_printf (out, "static void ___object_set_property "
3907 "(GObject *object, guint property_id, "
3908 "const GValue *value, GParamSpec *pspec);\n");
3910 if (get_properties > 0) {
3911 out_printf (out, "static void ___object_get_property "
3912 "(GObject *object, guint property_id, "
3913 "GValue *value, GParamSpec *pspec);\n");
3916 out_printf (outh, "\n/*\n"
3917 " * Public methods\n"
3920 if (!overrode_get_type && !no_gnu) {
3922 * For ordinary "static" types it should be safe to mark the
3923 * get_type implementation as const, since the get_type
3924 * function return really is constant at the call boundary
3925 * (even though there is an initial setup on the first call).
3926 * But for dynamic types, since the registration is explicitly
3927 * separated, we need to settle for "pure" as the results of
3928 * get_type differ before and after type registration.
3930 out_printf(outh, "GType\t%s_get_type\t(void) %s;\n", funcbase,
3931 c->dynamic ? "G_GNUC_PURE" : "G_GNUC_CONST");
3935 out_printf(outh, "void\t%s_register_type\t(GTypeModule *);\n",
3939 for(li = c->nodes; li != NULL; li = li->next) {
3941 if(n->type == METHOD_NODE) {
3942 put_pub_method((Method *)n);
3943 put_prot_method((Method *)n);
3944 put_priv_method_prot((Method *)n);
3948 /* this idea is less and less apealing to me */
3950 out_printf (outh, "\n/*\n"
3951 " * Signal connection wrapper macros\n"
3954 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3955 put_signal_macros (c, TRUE);
3956 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3957 put_signal_macros (c, FALSE);
3958 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n");
3960 put_signal_macros (c, FALSE);
3961 out_printf(outh, "\n");
3964 out_printf (out, "\n/*\n"
3965 " * Signal connection wrapper macro shortcuts\n"
3967 put_local_signal_macros (c);
3968 out_printf(outh, "\n");
3971 /* argument wrapping macros */
3972 if(get_properties > 0 || set_properties > 0) {
3973 out_printf(outh, "\n/*\n"
3974 " * Argument wrapping macros\n"
3977 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3978 put_argument_gnu_wrappers(c);
3979 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3980 put_argument_nongnu_wrappers(c);
3981 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n");
3983 put_argument_nongnu_wrappers(c);
3988 for(li = c->nodes; li != NULL; li = li->next) {
3990 if(n->type == METHOD_NODE)
3991 add_signal_prots((Method *)n);
3997 if(any_method_to_alias(c)) {
3998 out_printf (out, "/* Short form macros */\n");
3999 make_method_aliases (c);
4002 add_interface_inits (c);
4004 if (!overrode_get_type) {
4005 if (c->bonobo_object_class != NULL)
4006 add_bonobo_object_get_type();
4007 else if (c->dynamic)
4008 add_dynamic_get_type();
4013 out_printf (out, "/* a macro for creating a new object of our type */\n");
4015 "#define GET_NEW ((%s *)g_object_new(%s_get_type(), NULL))\n\n",
4016 typebase, funcbase);
4018 out_printf (out, "/* a function for creating a new object of our type */\n");
4019 out_printf (out, "#include <stdarg.h>\n");
4021 "static %s * GET_NEW_VARG (const char *first, ...)%s;\n"
4022 "static %s *\nGET_NEW_VARG (const char *first, ...)\n"
4023 "{\n\t%s *ret;\n\tva_list ap;\n"
4024 "\tva_start (ap, first);\n"
4025 "\tret = (%s *)g_object_new_valist (%s_get_type (), "
4028 "\treturn ret;\n}\n\n",
4030 no_gnu ? "" : " G_GNUC_UNUSED",
4031 typebase, typebase, typebase, funcbase);
4035 out_printf (out, "/* a function to connect glade callback */\n");
4036 out_printf (out,"static void\n"
4037 "___glade_xml_connect_foreach(const gchar *handler_name,\n"
4038 "GObject *object,\n"
4039 "const gchar *signal_name,\n"
4040 "const gchar *signal_data,\n"
4041 "GObject *connect_object,\n"
4043 "gpointer user_data)\n"
4045 "\tstatic GModule * allsymbols = NULL;\n"
4047 "\tif (!allsymbols) allsymbols = g_module_open(NULL, 0);\n"
4048 "\tif (allsymbols) {\n"
4049 "\t\tgchar * func_name = g_strdup_printf(\"%s_%%s\", handler_name);\n"
4050 "\t\tGCallback func;\n"
4052 "\t\tif (!g_module_symbol(allsymbols, func_name, (gpointer)&func)){\n"
4053 "\t\t\tif (!g_module_symbol(allsymbols, handler_name, (gpointer)&func)) {\n"
4054 "\t\t\t\tg_warning(\"could not find signal handler '%%s'.\", func_name);\n"
4055 "\t\t\t\tg_free(func_name);\n"
4060 "\t\t\tg_signal_connect_data(object, signal_name, func, user_data, NULL, G_CONNECT_AFTER | G_CONNECT_SWAPPED);\n"
4062 "\t\t\tg_signal_connect_data(object, signal_name, func, user_data, NULL, G_CONNECT_SWAPPED);\n"
4063 "\t\tg_free(func_name);\n"
4070 for (li = nodes; li != NULL; li = li->next) {
4071 Node *node = li->data;
4072 if (node->type == CCODE_NODE) {
4073 CCode *cc = (CCode *)node;
4074 if (cc->cctype == AD_CCODE)
4075 print_ccode_block (cc);
4079 if (need_constructor)
4080 add_constructor (c);
4090 if(set_properties > 0) {
4091 add_getset_arg(c, TRUE);
4094 if(get_properties > 0) {
4095 add_getset_arg(c, FALSE);
4098 for(li = c->nodes; li != NULL; li = li->next) {
4100 if(n->type == METHOD_NODE)
4101 put_method((Method *)n);
4104 add_bad_hack_to_avoid_unused_warnings(c);
4108 print_useful_macros(void)
4110 int major = 0, minor = 0, pl = 0;
4113 sscanf (VERSION, "%d.%d.%d", &major, &minor, &pl);
4114 out_printf (out, "#define GOB_VERSION_MAJOR %d\n", major);
4115 out_printf (out, "#define GOB_VERSION_MINOR %d\n", minor);
4116 out_printf (out, "#define GOB_VERSION_PATCHLEVEL %d\n\n", pl);
4118 /* Useful priv macro thingie */
4119 /* FIXME: this should be done the same way that priv is, as a var,
4121 out_printf (out, "#define selfp (self->_priv)\n\n");
4125 print_more_useful_macros (void)
4128 out_printf (out, "#define ___GOB_LIKELY(expr) (expr)\n");
4129 out_printf (out, "#define ___GOB_UNLIKELY(expr) (expr)\n");
4131 out_printf (out, "#ifdef G_LIKELY\n");
4132 out_printf (out, "#define ___GOB_LIKELY(expr) G_LIKELY(expr)\n");
4133 out_printf (out, "#define ___GOB_UNLIKELY(expr) G_UNLIKELY(expr)\n");
4134 out_printf (out, "#else /* ! G_LIKELY */\n");
4135 out_printf (out, "#define ___GOB_LIKELY(expr) (expr)\n");
4136 out_printf (out, "#define ___GOB_UNLIKELY(expr) (expr)\n");
4137 out_printf (out, "#endif /* G_LIKELY */\n");
4142 print_file_comments(void)
4144 out_printf(outh, "/* Generated by GOB (v%s)"
4145 " (do not edit directly) */\n\n", VERSION);
4147 out_printf(outph, "/* Generated by GOB (v%s)"
4148 " (do not edit directly) */\n\n", VERSION);
4149 out_printf(out, "/* Generated by GOB (v%s)"
4150 " (do not edit directly) */\n\n", VERSION);
4152 out_printf(out, "/* End world hunger, donate to the World Food Programme, http://www.wfp.org */\n\n");
4156 print_includes(void)
4158 gboolean found_header;
4161 /* We may need string.h for memset */
4162 if ( ! g_list_find_custom(include_files, "string.h", (GCompareFunc)strcmp)) {
4163 out_printf(out, "#include <string.h> /* memset() */\n\n");
4166 p = g_strconcat(filebase, ".h", NULL);
4167 found_header = TRUE;
4168 if( ! g_list_find_custom(include_files, p, (GCompareFunc)strcmp)) {
4169 out_printf(out, "#include \"%s.h\"\n\n", filebase);
4170 found_header = FALSE;
4174 /* if we are creating a private header see if it was included */
4176 char sep[2] = {0,0};
4179 p = g_strconcat(filebase, sep, "private.h", NULL);
4180 if( ! g_list_find_custom(include_files, p,
4181 (GCompareFunc)strcmp)) {
4182 out_printf(out, "#include \"%s%sprivate.h\"\n\n",
4186 error_printf(GOB_WARN, 0,
4187 "Implicit private header include "
4189 "\tsource file, while public "
4190 "header is at a custom location, "
4192 "\texplicitly include "
4193 "the private header below the "
4201 print_header_prefixes(void)
4205 p = replace_sep(((Class *)class)->otype, '_');
4207 out_printf(outh, "#ifndef __%s_H__\n#define __%s_H__\n\n", p, p);
4209 out_printf(outph, "#ifndef __%s_PRIVATE_H__\n"
4210 "#define __%s_PRIVATE_H__\n\n"
4211 "#include \"%s.h\"\n\n", p, p, filebase);
4214 if( ! no_extern_c) {
4215 out_printf(outh, "#ifdef __cplusplus\n"
4217 "#endif /* __cplusplus */\n\n");
4219 out_printf(outph, "#ifdef __cplusplus\n"
4221 "#endif /* __cplusplus */\n\n");
4226 print_header_postfixes(void)
4229 out_printf(outh, "\n#ifdef __cplusplus\n"
4231 "#endif /* __cplusplus */\n");
4232 out_printf(outh, "\n#endif\n");
4235 out_printf(outph, "\n#ifdef __cplusplus\n"
4237 "#endif /* __cplusplus */\n");
4238 out_printf(outph, "\n#endif\n");
4247 /* print the AT_CCODE and CT_CCODE blocks */
4248 for(li = nodes; li != NULL; li = li->next) {
4249 Node *node = li->data;
4250 if(node->type == CCODE_NODE) {
4251 CCode *cc = (CCode *)node;
4252 if (cc->cctype == AT_CCODE ||
4253 cc->cctype == CT_CCODE)
4254 print_ccode_block((CCode *)node);
4260 print_header_top(void)
4264 /* mandatory includes */
4265 out_printf (outh, "#include <glib.h>\n");
4266 out_printf (outh, "#include <glib-object.h>\n");
4268 /* print the HT_CCODE blocks */
4269 for (li = nodes; li != NULL; li = li->next) {
4270 Node *node = li->data;
4271 if (node->type == CCODE_NODE) {
4272 CCode *cc = (CCode *)node;
4273 if (cc->cctype == HT_CCODE)
4274 print_ccode_block ((CCode *)node);
4280 print_enum (EnumDef *enode)
4287 funcprefix = replace_sep (enode->etype, '_');
4288 gob_strdown (funcprefix);
4289 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
4291 type = remove_sep (enode->etype);
4293 out_printf (outh, "\ntypedef enum {\n");
4295 for (li = enode->values; li != NULL; li = li->next) {
4296 EnumValue *value = li->data;
4298 char *sname = gob_strdown (g_strdup (value->name));
4300 while ((p = strchr (sname, '_')) != NULL)
4303 out_printf (outh, "\t%s_%s", enode->prefix, value->name);
4304 if (value->value != NULL)
4305 out_printf (outh, " = %s", value->value);
4306 if (li->next != NULL)
4307 out_printf (outh, ",\n");
4309 out_printf (outh, "\n");
4311 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
4312 enode->prefix, value->name,
4313 enode->prefix, value->name,
4319 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
4321 out_printf (outh, "} %s;\n", type);
4323 str = make_pre_macro (enode->etype, "TYPE");
4324 out_printf (outh, "#define %s ", str);
4327 out_printf (outh, "%s_get_type()\n", funcprefix);
4328 out_printf (outh, "GType %s_get_type (void)%s;\n\n",
4329 funcprefix, no_gnu ? "": " G_GNUC_CONST");
4332 "GType\n%s_get_type (void)\n"
4334 "\tstatic GType type = 0;\n"
4335 "\tif ___GOB_UNLIKELY(type == 0)\n"
4336 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
4339 funcprefix, type, funcprefix);
4341 g_free (funcprefix);
4346 print_flags (Flags *fnode)
4354 funcprefix = replace_sep (fnode->ftype, '_');
4355 gob_strdown (funcprefix);
4356 out_printf (out, "static const GFlagsValue _%s_values[] = {\n",
4358 type = remove_sep (fnode->ftype);
4360 out_printf (outh, "\ntypedef enum {\n");
4362 for (i = 0, li = fnode->values; li != NULL; i++, li = li->next) {
4363 const char *name = li->data;
4365 char *sname = gob_strdown (g_strdup (name));
4367 while ((p = strchr (sname, '_')) != NULL)
4370 out_printf (outh, "\t%s_%s = 1<<%d",
4371 fnode->prefix, name, i);
4372 if (li->next != NULL)
4373 out_printf (outh, ",\n");
4375 out_printf (outh, "\n");
4377 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
4378 fnode->prefix, name,
4379 fnode->prefix, name,
4385 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
4387 out_printf (outh, "} %s;\n", type);
4389 str = make_pre_macro (fnode->ftype, "TYPE");
4390 out_printf (outh, "#define %s ", str);
4393 out_printf (outh, "%s_get_type()\n", funcprefix);
4394 out_printf (outh, "GType %s_get_type (void)%s;\n\n",
4395 funcprefix, no_gnu ? "" : " G_GNUC_CONST");
4398 "GType\n%s_get_type (void)\n"
4400 "\tstatic GType type = 0;\n"
4401 "\tif ___GOB_UNLIKELY(type == 0)\n"
4402 "\t\ttype = g_flags_register_static (\"%s\", _%s_values);\n"
4405 funcprefix, type, funcprefix);
4407 g_free (funcprefix);
4412 print_error (Error *enode)
4419 funcprefix = replace_sep (enode->etype, '_');
4420 gob_strdown (funcprefix);
4421 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
4423 type = remove_sep (enode->etype);
4425 out_printf (outh, "\ntypedef enum {\n");
4427 for (li = enode->values; li != NULL; li = li->next) {
4428 const char *name = li->data;
4430 char *sname = gob_strdown (g_strdup (name));
4432 while ((p = strchr (sname, '_')) != NULL)
4435 out_printf (outh, "\t%s_%s", enode->prefix, name);
4436 if (li->next != NULL)
4437 out_printf (outh, ",\n");
4439 out_printf (outh, "\n");
4441 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
4442 enode->prefix, name,
4443 enode->prefix, name,
4449 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
4451 out_printf (outh, "} %s;\n", type);
4453 str = make_pre_macro (enode->etype, "TYPE");
4454 out_printf (outh, "#define %s ", str);
4457 out_printf (outh, "%s_get_type ()\n", funcprefix);
4458 out_printf (outh, "GType %s_get_type (void)%s;\n\n",
4459 funcprefix, no_gnu ? "" : " G_GNUC_CONST");
4462 "GType\n%s_get_type (void)\n"
4464 "\tstatic GType type = 0;\n"
4465 "\tif ___GOB_UNLIKELY(type == 0)\n"
4466 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
4469 funcprefix, type, funcprefix);
4471 out_printf (outh, "#define %s %s_quark ()\n", enode->prefix, funcprefix);
4472 out_printf (outh, "GQuark %s_quark (void);\n\n", funcprefix);
4474 str = replace_sep (enode->etype, '-');
4478 "GQuark\n%s_quark (void)\n"
4480 "\tstatic GQuark q = 0;\n"
4482 "\t\tq = g_quark_from_static_string (\"%s\");\n"
4489 g_free (funcprefix);
4494 generate_outfiles(void)
4498 print_file_comments();
4504 print_header_prefixes();
4506 print_useful_macros();
4510 print_more_useful_macros ();
4512 for (li = nodes; li != NULL; li = li->next) {
4513 Node *node = li->data;
4514 if (node->type == CCODE_NODE) {
4515 CCode *cc = (CCode *)node;
4516 if (cc->cctype != HT_CCODE &&
4517 cc->cctype != AT_CCODE &&
4518 cc->cctype != AD_CCODE)
4519 print_ccode_block ((CCode *)node);
4520 } else if (node->type == CLASS_NODE) {
4521 print_class_block ((Class *)node);
4522 } else if (node->type == ENUMDEF_NODE) {
4523 print_enum ((EnumDef *)node);
4524 } else if (node->type == FLAGS_NODE) {
4525 print_flags ((Flags *)node);
4526 } else if (node->type == ERROR_NODE) {
4527 print_error ((Error *)node);
4529 g_assert_not_reached();
4533 print_header_postfixes();
4536 static void print_version(void)
4538 printf("%s (%s) %s\n", PACKAGE_NAME, PACKAGE_TARNAME, PACKAGE_VERSION);
4539 puts("Copyright (C) 2013 George (Jiri) Lebl et al.");
4540 puts("Copyright (C) 2022 Nick Bowler");
4541 puts("License GPLv2+: GNU GPL version 2 or any later version");
4542 puts("This is free software: you are free to change and redistribute it.");
4543 puts("There is NO WARRANTY, to the extent permitted by law.");
4546 static void print_usage(FILE *f)
4548 fprintf(f, "Usage: %s [options] file.gob\n", g_get_prgname());
4550 fprintf(f, "Try '%s --help' for more information.\n",
4555 static void print_help(void)
4557 const struct option *opt;
4559 print_usage(stdout);
4561 puts("This is \"GObject Builder\": a simple preprocessor to help with\n"
4562 "implementing GObject types in C.");
4565 for (opt = lopts; opt->name; opt++) {
4566 struct lopt_help help;
4568 /* Don't display obsolete options that don't do anything */
4569 if (!opt->flag && !opt->val)
4572 if (!lopt_get_help(opt, &help))
4575 help_print_option(opt, help.arg, help.desc, 20);
4579 puts("End world hunger, donate to the World Food Programme: https://www.wfp.org/");
4583 * Called after getopt_long receives an --m4 argument. Immediately stop
4584 * processing options. Then all non-option arguments seen so far together
4585 * with all remaining arguments are appended to M4_COMMANDLINE. If m4_clean
4586 * is false, then M4_FLAGS is inserted before the first non-option argument,
4589 * The resulting string is returned, which should be freed by the caller.
4591 static char *parse_m4_options(int argc, char **argv, gboolean m4_clean)
4593 char **nonopt = NULL, *save_argv0, *ret;
4596 /* First, conclude getopt run and reset with remaining args */
4597 getopt_long(optind, argv, sopts, lopts, NULL);
4602 save_argv0 = argv[0];
4603 argv[0] = M4_COMMANDLINE;
4606 ret = g_strjoinv(" ", argv);
4607 argv[0] = save_argv0;
4611 /* Locate first non-option argument, if any. */
4612 while ((opt = getopt_long(argc, argv, "-", NULL, NULL)) != -1) {
4614 nonopt = &argv[optind-2];
4619 /* If there is a non-option but the above didn't see it, must be "--" */
4620 if (!nonopt && argv[optind])
4621 nonopt = &argv[optind-2];
4624 /* Found non-option, insert M4_FLAGS just before it. */
4625 char *save_argv[3] = { nonopt[0], nonopt[1], nonopt[2] };
4627 nonopt[1] = M4_FLAGS;
4629 nonopt[0] = g_strjoinv(" ", argv);
4631 nonopt[1] = save_argv[1];
4632 nonopt[2] = save_argv[2];
4633 ret = g_strjoinv(" ", nonopt);
4636 nonopt[0] = save_argv[0];
4638 /* Only options, not inserting M4_FLAGS. */
4639 ret = g_strjoinv(" ", argv);
4642 argv[0] = save_argv0;
4646 static int parse_options(int argc, char **argv)
4648 gboolean show_m4_dir = FALSE, m4_clean = FALSE;
4649 char *raw_file_sep = "-";
4653 while ((opt = getopt_long(argc, argv, sopts, lopts, NULL)) != -1) {
4659 output_dir = optarg;
4662 exit_on_warn = TRUE;
4665 raw_file_sep = optarg ? optarg : "";
4671 no_touch = no_touch_headers = TRUE;
4677 m4_commandline = parse_m4_options(argc, argv, m4_clean);
4683 if (optopt == '?') {
4689 /* Rewind getopt to get internal error messages. */
4690 optind = 0, opterr = 1;
4691 while (getopt_long(argc, argv, sopts, lopts, NULL)
4694 case 0: /* no-op or option set by flag */;
4698 filename = argv[optind];
4699 if (argc > optind+1) {
4700 char *s = g_strjoinv(" ", argv+optind+1);
4701 fprintf(stderr, "%s: Warning: excess arguments ignored: %s\n",
4702 g_get_prgname(), s);
4708 file_sep = raw_file_sep[0];
4709 if (raw_file_sep[0] && raw_file_sep[1]) {
4710 fprintf(stderr, "%s: Warning: --file-sep characters beyond the first are ignored\n",
4717 printf("%s\n", M4_INCLUDE_DIR);
4725 compare_and_move (const char *old_filename)
4727 char *new_filename = g_strconcat (old_filename, "#gob#", NULL);
4729 gboolean equal = FALSE;
4731 old_f = fopen (old_filename, "r");
4734 gboolean error = FALSE;
4736 new_f = fopen (new_filename, "r");
4745 new_n = fread (new_buf, 1, sizeof (new_buf), new_f);
4746 if (ferror (new_f)) {
4748 error_printf (GOB_ERROR, 0,
4749 "Can't read %s: %s",
4751 g_strerror (errno));
4755 old_n = fread (old_buf, 1, sizeof (old_buf), old_f);
4757 || feof (new_f) != feof (old_f)
4759 || memcmp (new_buf, old_buf, new_n) != 0)
4768 error_printf (GOB_ERROR, 0, "Can't open %s: %s",
4769 new_filename, g_strerror (errno));
4777 if (! equal && unlink (old_filename) != 0) {
4778 error_printf (GOB_ERROR, 0, "Can't remove %s: %s",
4779 old_filename, g_strerror (errno));
4785 if (unlink (new_filename) != 0)
4786 error_printf (GOB_ERROR, 0, "Can't remove %s: %s",
4787 new_filename, g_strerror (errno));
4789 if (rename (new_filename, old_filename) != 0)
4790 error_printf (GOB_ERROR, 0, "Can't rename %s to %s: %s",
4791 new_filename, old_filename,
4792 g_strerror (errno));
4796 g_free (new_filename);
4800 main(int argc, char *argv[])
4804 g_set_prgname(argc > 0 ? argv[0] : "gob2");
4806 rc = parse_options(argc, argv);
4808 print_usage(stderr);
4809 return EXIT_FAILURE;
4810 } else if (rc > 0) {
4811 return EXIT_SUCCESS;
4815 yyin = popen(m4_commandline, "r");
4817 fprintf(stderr, "Error: can't open pipe from '%s'\n",
4821 } else if(filename) {
4822 yyin = fopen(filename, "r");
4824 fprintf(stderr, "Error: can't open file '%s'\n",
4833 /* This is where parsing is done */
4836 error_print (GOB_ERROR, 0, "Parsing errors, quitting");
4838 /* close input file */
4839 if(use_m4) pclose(yyin);
4844 error_print (GOB_ERROR, 0, "no class defined");
4847 exit_on_error = FALSE;
4849 signals = count_signals ((Class *)class);
4850 set_properties = count_set_properties ((Class *)class) +
4851 count_set_arguments ((Class *)class);
4852 get_properties = count_get_properties ((Class *)class) +
4853 count_get_arguments ((Class *)class);
4854 overrides = count_overrides ((Class *)class);
4855 privates = count_privates ((Class *)class);
4856 protecteds = count_protecteds ((Class *)class);
4857 unreftors = count_unreftors ((Class *)class);
4858 destructors = count_destructors ((Class *)class);
4859 initializers = count_initializers ((Class *)class);
4860 glade_widgets = count_glade_widgets ((Class *)class);
4861 overrode_get_type = find_get_type ((Class *)class);
4864 make_inits ((Class *)class);
4866 find_constructor ((Class *)class);
4867 if (user_constructor != NULL)
4868 need_constructor = TRUE;
4870 find_dispose ((Class *)class);
4871 if (unreftors > 0 ||
4872 dispose_handler != NULL ||
4873 user_dispose_method != NULL)
4874 need_dispose = TRUE;
4876 find_finalize ((Class *)class);
4877 if (destructors > 0 ||
4879 user_finalize_method != NULL) {
4880 need_finalize = TRUE;
4883 check_bad_symbols ((Class *)class);
4884 check_duplicate_symbols ((Class *)class);
4885 check_duplicate_overrides ((Class *)class);
4886 check_duplicate_signals_args ((Class *)class);
4887 check_public_new ((Class *)class);
4888 check_vararg ((Class *)class);
4889 check_firstarg ((Class *)class);
4890 check_nonvoidempty ((Class *)class);
4891 check_signal_args ((Class *)class);
4892 check_property_types ((Class *)class);
4893 check_argument_types ((Class *)class);
4894 check_func_arg_checks ((Class *)class);
4895 check_func_attrs ((Class *)class);
4896 check_for_class_destructors ((Class *)class);
4898 exit_on_error = TRUE;
4903 any_special = setup_special_array ((Class *)class, special_array);
4907 generate_outfiles ();
4918 compare_and_move(outfilebase);
4920 if (no_touch_headers) {
4921 compare_and_move(outfilehbase);
4923 compare_and_move(outfilephbase);