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-2020 Nick Bowler
7 * Author: George (Jiri) Lebl
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
35 #include "treefuncs.h"
43 char *filename = NULL;
53 extern GList *include_files;
55 extern GHashTable *gtk_doc_hash;
59 static char *outfilebase;
60 static char *outfilehbase;
61 static char *outfilephbase;
62 static char *funcbase;
63 static char *pfuncbase;
64 static char *macrobase;
66 static char *pmacrois;
67 static char *macrotype;
68 static char *pmacrotype;
69 static char *typebase;
70 static char *ptypebase;
72 char *output_dir = NULL;
76 static int signals = 0; /* number of signals */
77 static int set_properties = 0; /* number of named (set) properties */
78 static int get_properties = 0; /* number of named (get) properties */
79 static int overrides = 0; /* number of override methods */
80 static int privates = 0; /* number of private data members */
81 static int protecteds = 0; /* number of protected methods */
82 static int unreftors = 0; /* number of variable unreffing destructors */
83 static int destructors = 0; /* number of variable non-unreffing destructors */
84 static int initializers = 0; /* number of variable initializers */
85 static int glade_widgets = 0; /* number of glade widgets */
86 static gboolean overrode_get_type = FALSE; /* provided your won _get_type */
88 static gboolean made_aliases = FALSE; /* if we made any shorthand aliases
89 and need the REALLY UGLY HACK to
92 /* the special variable types we need to define */
93 static gboolean special_array[SPECIAL_LAST] = {0};
94 static gboolean any_special = FALSE;
96 static gboolean need_constructor = FALSE;
97 static Method * user_constructor = NULL;
99 static gboolean need_dispose = FALSE;
100 static Method * dispose_handler = NULL;
101 static Method * user_dispose_method = NULL;
103 static gboolean need_finalize = FALSE;
104 static Method * finalize_handler = NULL;
105 static Method * user_finalize_method = NULL;
111 gboolean no_touch = FALSE;
112 gboolean no_touch_headers = FALSE;
113 gboolean for_cpp = FALSE;
114 gboolean no_gnu = FALSE;
115 gboolean exit_on_warn = FALSE;
116 gboolean exit_on_error = TRUE;
117 gboolean got_error = FALSE;
118 gint private_header = PRIVATE_HEADER_ONDEMAND;
119 gboolean no_extern_c = FALSE;
120 gboolean no_write = FALSE;
121 gboolean no_lines = FALSE;
122 gboolean no_self_alias = FALSE;
123 gboolean always_private_struct = FALSE;
124 gboolean gtk3_ok = FALSE;
130 gboolean use_m4 = FALSE; /* preprocess sources with m4 */
131 gboolean use_m4_clean = FALSE; /* preprocess sources with m4, no m4 flags */
132 char *m4_commandline = NULL;
133 #define M4_INCLUDE_DIR PKGDATADIR "/m4"
134 #define M4_BASE_FILENAME "gobm4.m4"
135 #define M4_FLAGS "-P -s -I" M4_INCLUDE_DIR " -DGOBM4_GOB_VERSION=" VERSION " " M4_BASE_FILENAME
136 #define M4_COMMANDLINE "m4"
138 int method_unique_id = 1;
143 filebase = replace_sep (((Class *)class)->otype, file_sep);
144 gob_strdown (filebase);
146 if (output_dir != NULL &&
147 output_dir[0] != '\0') {
148 fullfilebase = g_build_filename (output_dir, filebase, NULL);
150 fullfilebase = g_strdup (filebase);
153 funcbase = replace_sep (((Class *)class)->otype, '_');
154 gob_strdown (funcbase);
156 pfuncbase = replace_sep (((Class *)class)->ptype, '_');
157 gob_strdown (pfuncbase);
159 macrobase = replace_sep (((Class *)class)->otype, '_');
160 gob_strup (macrobase);
162 macrois = make_pre_macro (((Class *)class)->otype, "IS");
163 pmacrois = make_pre_macro (((Class *)class)->ptype, "IS");
165 macrotype = make_pre_macro (((Class *)class)->otype, "TYPE");
166 pmacrotype = make_pre_macro (((Class *)class)->ptype, "TYPE");
168 typebase = remove_sep (((Class *)class)->otype);
170 ptypebase = remove_sep (((Class *)class)->ptype);
174 get_gtk_doc (const char *id)
181 val = g_hash_table_lookup(gtk_doc_hash, id);
183 return g_strdup_printf("/**\n * %s_%s:\n%s **/\n",
185 val = g_hash_table_lookup(gtk_doc_hash, id);
187 return g_strdup_printf("/**\n * %s_%s:\n%s **/\n",
193 print_type(FILE *fp, const Type *t, gboolean postfix_to_stars)
197 s = get_type(t, postfix_to_stars);
198 out_printf(fp, "%s", s);
204 print_method (FILE *fp,
205 const char *typeprefix,
206 const char *nameprefix,
207 const char *subnameprefix,
208 const char *namepostfix,
209 const char *afterargs,
212 gboolean print_funcattrs,
213 gboolean one_arg_per_line,
214 gboolean no_funcbase,
215 gboolean kill_underscore,
216 gboolean first_unused,
222 out_printf(fp, "%s", typeprefix);
223 print_type(fp, m->mtype, TRUE);
228 out_printf(fp, "%s%s%s%s(",
229 nameprefix, subnameprefix, id, namepostfix);
231 out_printf(fp, "%s%s_%s%s%s(",
232 nameprefix, funcbase, subnameprefix, id,
236 for(li=m->args; li; li=g_list_next(li)) {
237 FuncArg *arg = li->data;
238 const char *unused = "";
241 ! for_cpp && /* g++ has a cow with this */
244 unused = " G_GNUC_UNUSED";
247 print_type(fp, arg->atype, FALSE);
249 out_printf (fp, "___fake___");
251 out_printf(fp, "%s%s%s,%s", arg->name,
252 arg->atype->postfix ?
253 arg->atype->postfix : "",
255 one_arg_per_line ? "\n\t\t\t\t\t" : " ");
257 out_printf(fp, "%s%s%s", arg->name,
258 arg->atype->postfix ?
259 arg->atype->postfix : "",
263 out_printf(fp, ",%s...",
264 one_arg_per_line ? "\n\t\t\t\t\t" : " ");
266 out_printf(fp, "void");
268 /* Slightly icky: sometimes we are called st m->funcattrs
269 hasn't been set, but if so it should be NULL since its been
271 if(print_funcattrs && m->funcattrs != NULL
272 && strlen(m->funcattrs) > 0) {
273 /* To keep the output neat, we trim off the trailing '\n'
274 from the end of funcattrs for a moment. */
275 size_t funcattrs_len = strlen(m->funcattrs);
276 gboolean funcattrs_chomped = FALSE;
277 if((m->funcattrs)[funcattrs_len - 1] == '\n') {
278 m->funcattrs[funcattrs_len - 1] = '\0';
279 funcattrs_chomped = TRUE;
281 out_printf(fp, "%s)\n%s%s", afterargs, m->funcattrs, postfix);
282 /* Put it back like it was (though it shouldn't matter). */
283 if (funcattrs_chomped) {
284 (m->funcattrs)[funcattrs_len - 1] = '\n';
288 out_printf(fp, "%s)%s", afterargs, postfix);
293 any_method_to_alias(Class *c)
297 for(li=c->nodes;li;li=g_list_next(li)) {
298 Node *node = li->data;
299 if(node->type == METHOD_NODE) {
300 Method *m = (Method *)node;
302 if(m->method == INIT_METHOD ||
303 m->method == CLASS_INIT_METHOD ||
304 m->method == CONSTRUCTOR_METHOD ||
305 m->method == DISPOSE_METHOD ||
306 m->method == FINALIZE_METHOD ||
307 m->method == OVERRIDE_METHOD)
318 make_method_aliases (Class *c)
322 for(li = c->nodes; li != NULL; li = li->next) {
323 Node *node = li->data;
324 if(node->type == METHOD_NODE) {
325 Method *m = (Method *)node;
327 if(m->method == INIT_METHOD ||
328 m->method == CLASS_INIT_METHOD ||
329 m->method == CONSTRUCTOR_METHOD ||
330 m->method == DISPOSE_METHOD ||
331 m->method == FINALIZE_METHOD ||
332 m->method == OVERRIDE_METHOD)
335 out_printf (out, "#define self_%s %s_%s\n",
344 add_bad_hack_to_avoid_unused_warnings(const Class *c)
348 /* if we haven't had any methods, just return */
353 out_printf(out, "\n\n#if (!defined __GNUC__) || (defined __GNUC__ && defined __STRICT_ANSI__)\n");
355 "/*REALLY BAD HACK\n"
356 " This is to avoid unused warnings if you don't call\n"
357 " some method. I need to find a better way to do\n"
358 " this, not needed in GCC since we use some gcc\n"
359 " extentions to make saner, faster code */\n"
361 "___%s_really_bad_hack_to_avoid_warnings(void)\n"
363 out_printf(out, "\t((void (*)(void))GET_NEW_VARG)();\n");
364 for(li=c->nodes;li;li=g_list_next(li)) {
365 Node *node = li->data;
366 if(node->type == METHOD_NODE) {
367 Method *m = (Method *)node;
369 if(m->method == INIT_METHOD ||
370 m->method == CLASS_INIT_METHOD ||
371 m->method == CONSTRUCTOR_METHOD ||
372 m->method == DISPOSE_METHOD ||
373 m->method == FINALIZE_METHOD ||
374 m->method == OVERRIDE_METHOD)
377 /* in C++ mode we don't alias new */
378 if(for_cpp && strcmp(m->id, "new")==0)
381 out_printf(out, "\t((void (*)(void))self_%s)();\n", m->id);
384 out_printf(out, "\t___%s_really_bad_hack_to_avoid_warnings();\n",
387 out_printf(out, "}\n#endif /* !__GNUC__ || (__GNUC__ && __STRICT_ANSI__) */\n\n");
389 out_printf(out, "}\n\n");
393 put_variable(const Variable *v, FILE *fp)
395 out_printf(fp, "\t");
396 print_type(fp, v->vtype, FALSE);
397 out_printf(fp, "%s%s;", v->id,
399 v->vtype->postfix:"");
400 if(v->scope == PROTECTED_SCOPE)
401 out_printf(fp, " /* protected */");
402 out_printf(fp, "\n");
406 put_vs_method(const Method *m)
408 if(m->method != SIGNAL_LAST_METHOD &&
409 m->method != SIGNAL_FIRST_METHOD &&
410 m->method != VIRTUAL_METHOD)
413 /* if a signal mark it as such */
414 if(m->method != VIRTUAL_METHOD)
415 print_method(outh, "\t/*signal*/", "(* ", "", ") ", "", ";\n",
416 m, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE);
418 print_method(outh, "\t", "(* ", "", ") ", "", ";\n",
419 m, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE);
424 put_pub_method(const Method *m)
426 if(m->scope != PUBLIC_SCOPE)
429 out_addline_infile(outh, m->line_no);
430 print_method(outh, "", "\t", "", "\t", "", ";\n", m,
431 TRUE, TRUE, FALSE, TRUE, FALSE, FALSE);
432 out_addline_outfile(outh);
436 put_signal_macro (const Method *m, gboolean gnu)
438 if(m->method != SIGNAL_LAST_METHOD &&
439 m->method != SIGNAL_FIRST_METHOD)
444 out_printf (outh, "#define %s_connect__%s(object,func,data)\t"
445 "g_signal_connect(%s(object),\"%s\","
446 "(GCallback)(func),(data))\n",
447 funcbase, m->id, macrobase, m->id);
450 out_printf (outh, "#define %s_connect_after__%s(object,func,data)\t"
451 "g_signal_connect_after(%s(object),\"%s\","
452 "(GCallback)(func),(data))\n",
453 funcbase, m->id, macrobase, m->id);
456 out_printf (outh, "#define %s_connect_data__%s"
457 "(object,func,data,destroy_data,flags)\t"
458 "g_signal_connect_data(%s(object),\"%s\","
459 "(GCallback)(func),(data),(destroy_data),(GConnectFlags)(flags))\n",
460 funcbase, m->id, macrobase, m->id);
463 out_printf (outh, "#define %s_connect__%s(object,func,data)\t"
465 "%s(__extension__ ({%s *___object = (object); ___object; })),"
467 "(GCallback) __extension__ ({",
468 funcbase, m->id, macrobase, typebase, m->id);
469 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
470 " = (func); ", m, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE);
471 out_printf (outh, "___%s; }), (data))\n", m->id);
474 out_printf (outh, "#define %s_connect_after__%s(object,func,data)\t"
475 "g_signal_connect_after("
476 "%s(__extension__ ({%s *___object = (object); ___object; })),"
478 "(GCallback) __extension__ ({",
479 funcbase, m->id, macrobase, typebase, m->id);
480 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
481 " = (func); ", m, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE);
482 out_printf (outh, "___%s; }), (data))\n", m->id);
485 out_printf (outh, "#define %s_connect_data__%s"
486 "(object,func,data,destroy_data,flags)\t"
487 "g_signal_connect_data("
488 "%s(__extension__ ({%s *___object = (object); ___object; })),"
490 "(GCallback) __extension__ ({",
491 funcbase, m->id, macrobase, typebase, m->id);
492 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
493 " = (func); ", m, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE);
494 out_printf (outh, "___%s; }), (data), (destroy_data), (GConnectFlags)(flags))\n", m->id);
499 put_signal_macros (const Class *c, gboolean gnu)
506 for (li = c->nodes; li != NULL; li = li->next) {
507 const Node *n = li->data;
508 if (n->type == METHOD_NODE)
509 put_signal_macro ((Method *)n, gnu);
514 put_local_signal_macro (const Method *m)
516 if(m->method != SIGNAL_LAST_METHOD &&
517 m->method != SIGNAL_FIRST_METHOD)
521 out_printf (out, "#define self_connect__%s(object,func,data)\t"
522 "%s_connect__%s((object),(func),(data))\n",
523 m->id, funcbase, m->id);
526 out_printf (out, "#define self_connect_after__%s(object,func,data)\t"
527 "%s_connect_after__%s((object),(func),(data))\n",
528 m->id, funcbase, m->id);
531 out_printf (out, "#define self_connect_data__%s(object,func,data,destroy_data,flags)\t"
532 "%s_connect_data__%s((object),(func),(data),(destroy_data),(flags))\n",
533 m->id, funcbase, m->id);
537 put_local_signal_macros (const Class *c)
544 for (li = c->nodes; li != NULL; li = li->next) {
545 const Node *n = li->data;
546 if (n->type == METHOD_NODE)
547 put_local_signal_macro ((Method *)n);
553 put_prot_method(const Method *m)
557 if(m->scope != PROTECTED_SCOPE)
560 f = outph ? outph : out;
562 out_addline_infile(f, m->line_no);
563 print_method(f, "", "\t", "", "\t", "", ";\n",
564 m, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE);
565 out_addline_outfile(f);
569 put_priv_method_prot(const Method *m)
571 if(m->method == SIGNAL_LAST_METHOD ||
572 m->method == SIGNAL_FIRST_METHOD ||
573 m->method == VIRTUAL_METHOD) {
576 "static ", "___real_", "", " ", "", ";\n",
577 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
579 /* no else, here, it might still have a private prototype, it's not
582 if((m->method == OVERRIDE_METHOD &&
585 char *s = g_strdup_printf("___%x_", (guint)m->unique_id);
587 out_addline_infile(out, m->line_no);
588 print_method(out, "static ", s, "", " ", "",
589 no_gnu?";\n":" G_GNUC_UNUSED;\n",
590 m, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE);
592 out_addline_outfile(out);
594 } else if(m->scope == PRIVATE_SCOPE ||
595 m->method == INIT_METHOD ||
596 m->method == CLASS_INIT_METHOD ||
597 m->method == CONSTRUCTOR_METHOD ||
598 m->method == DISPOSE_METHOD ||
599 m->method == FINALIZE_METHOD) {
601 out_addline_infile(out, m->line_no);
602 print_method(out, "static ", "", "", " ", "",
603 no_gnu?";\n":" G_GNUC_UNUSED;\n",
604 m, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE);
606 out_addline_outfile(out);
611 make_func_arg (const char *typename, gboolean is_class, const char *name)
618 tn = g_strconcat (typename, ":Class", NULL);
620 tn = g_strdup (typename);
622 type = node_new (TYPE_NODE,
626 node = node_new (FUNCARG_NODE,
627 "atype:steal", (Type *)type,
630 return g_list_prepend (NULL, node);
634 make_inits(Class *cl)
636 int got_class_init = FALSE;
637 int got_init = FALSE;
640 for(li=cl->nodes;li;li=g_list_next(li)) {
642 if(n->type == METHOD_NODE) {
643 Method *m = (Method *)n;
644 if(m->method == INIT_METHOD) {
646 error_print(GOB_ERROR, m->line_no, "init defined more then once");
648 } else if(m->method == CLASS_INIT_METHOD) {
650 error_print(GOB_ERROR, m->line_no, "class_init defined more then once");
651 got_class_init = TRUE;
655 if(!got_class_init) {
656 Type *type = (Type *)node_new (TYPE_NODE,
659 node = node_new (METHOD_NODE,
661 "method", CLASS_INIT_METHOD,
664 "args:steal", make_func_arg (cl->otype,
667 "unique_id", method_unique_id++,
669 cl->nodes = g_list_prepend(cl->nodes, node);
672 Type *type = (Type *)node_new (TYPE_NODE,
675 node = node_new (METHOD_NODE,
677 "method", INIT_METHOD,
680 "args:steal", make_func_arg (cl->otype,
681 FALSE /* is_class */,
683 "unique_id", method_unique_id++,
685 cl->nodes = g_list_prepend(cl->nodes, node);
690 find_method(const Class *cl, int method, const char *id)
694 for(li=cl->nodes;li;li=g_list_next(li)) {
696 if(n->type == METHOD_NODE) {
697 Method *m = (Method *)n;
698 if (m->method == method
699 && (id == NULL || strcmp(m->id, id)==0))
708 find_constructor(const Class *cl)
710 user_constructor = find_method(cl, CONSTRUCTOR_METHOD, NULL);
714 find_dispose(const Class *cl)
716 dispose_handler = find_method(cl, OVERRIDE_METHOD, "dispose");
717 if (dispose_handler != NULL) {
718 if(strcmp(dispose_handler->otype, "G:Object") != 0)
719 error_print(GOB_ERROR, dispose_handler->line_no,
720 "dispose method override "
721 "of class other then "
723 if(g_list_length(dispose_handler->args) != 1)
724 error_print(GOB_ERROR, dispose_handler->line_no,
725 "dispose method override "
726 "with more then one "
730 user_dispose_method = find_method(cl, DISPOSE_METHOD, NULL);
734 find_finalize(const Class *cl)
736 finalize_handler = find_method(cl, OVERRIDE_METHOD, "finalize");
737 if (finalize_handler != NULL) {
738 if(strcmp(finalize_handler->otype, "G:Object") != 0)
739 error_print(GOB_ERROR, finalize_handler->line_no,
740 "finalize method override "
741 "of class other then "
743 if(g_list_length(finalize_handler->args) != 1)
744 error_print(GOB_ERROR, finalize_handler->line_no,
745 "finalize method override "
746 "with more then one "
750 user_finalize_method = find_method(cl, FINALIZE_METHOD, NULL);
754 /* hash of method -> name of signal prototype */
755 static GHashTable *marsh = NULL;
757 /* list of methods with different signal prototypes,
758 we check this list if we can use a signal prototype of a
759 previous signal method, there are only uniques here */
760 static GList *eq_signal_methods = NULL;
762 /* compare a list of strings */
764 is_list_equal(const GList *a, const GList *b)
766 for(;a && b; a=a->next, b=b->next) {
767 if(strcmp(a->data, b->data)!=0) {
771 /* the the lists were different length */
778 find_same_type_signal(const Method *m)
781 for(li=eq_signal_methods;li;li=li->next) {
782 Method *mm = li->data;
783 if(is_list_equal(mm->gtktypes, m->gtktypes))
790 print_signal_marsal_args (const Method *m)
792 if (strcmp (m->gtktypes->next->data, "NONE") != 0) {
795 for (i = 0, li = m->gtktypes->next;
797 i++, li = li->next) {
800 if (strcmp (li->data, "UNICHAR") == 0)
801 /* hack because glib is braindamaged */
802 get_func = g_strdup ("g_value_get_uint");
803 else if (strncmp(li->data, "BOXED_", 6) == 0)
804 get_func = g_strdup ("g_value_get_boxed");
806 get_func = g_strdup_printf
807 ("g_value_get_%s", (char *)li->data);
809 gob_strdown (get_func);
810 out_printf (out, ",\n\t\t(%s) "
811 "%s (param_values + %d)",
812 get_cast (li->data, FALSE),
817 out_printf (out, ",\n\t\tdata2);\n");
822 add_signal_prots(Method *m)
828 gboolean ret_none = FALSE;
829 gboolean arglist_none = FALSE;
831 const char *unused = "";
833 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
834 unused = " G_GNUC_UNUSED";
837 if (m->method != SIGNAL_LAST_METHOD &&
838 m->method != SIGNAL_FIRST_METHOD)
842 marsh = g_hash_table_new(NULL, NULL);
844 g_assert (m->gtktypes->next != NULL);
846 ret_none = strcmp(m->gtktypes->data, "NONE") == 0;
847 arglist_none = strcmp(m->gtktypes->next->data, "NONE") == 0;
849 if (ret_none && arglist_none)
852 /* if we already did a signal prototype just use that */
853 mm = find_same_type_signal (m);
855 s = g_hash_table_lookup (marsh, mm);
856 g_hash_table_insert (marsh, m, s);
863 retcast = get_cast (m->gtktypes->data, FALSE);
865 s = g_strdup_printf("Sig%d", sig++);
867 g_hash_table_insert(marsh, m, s);
868 eq_signal_methods = g_list_prepend(eq_signal_methods, m);
870 /* we know that we'll know all the gtktypes (so get_cast can't fail) */
871 out_printf(out, "\ntypedef %s (*___%s) (%s *, ",
872 get_cast(m->gtktypes->data, FALSE), s, typebase);
874 if ( ! arglist_none) {
875 for (li = m->gtktypes->next; li != NULL; li = li->next)
876 out_printf (out, "%s, ", get_cast (li->data, FALSE));
878 out_printf (out, "gpointer);\n");
880 out_printf (out, "\nstatic void\n"
881 "___marshal_%s (GClosure *closure,\n"
882 "\tGValue *return_value%s,\n"
883 "\tguint n_param_values,\n"
884 "\tconst GValue *param_values,\n"
885 "\tgpointer invocation_hint%s,\n"
886 "\tgpointer marshal_data)\n"
893 out_printf (out, "\t%s v_return;\n", retcast);
895 out_printf (out, "\tregister ___%s callback;\n"
896 "\tregister GCClosure *cc = (GCClosure*) closure;\n"
897 "\tregister gpointer data1, data2;\n\n",
900 out_printf (out, "\tg_return_if_fail (n_param_values == %d);\n\n",
901 arglist_none ? 1 : g_list_length (m->gtktypes));
904 "\tif (G_CCLOSURE_SWAP_DATA (closure)) {\n"
905 "\t\tdata1 = closure->data;\n"
906 "\t\tdata2 = g_value_peek_pointer (param_values + 0);\n"
908 "\t\tdata1 = g_value_peek_pointer (param_values + 0);\n"
909 "\t\tdata2 = closure->data;\n"
912 out_printf (out, "\tcallback = (___%s) "
913 "(marshal_data != NULL ? marshal_data : cc->callback);"
917 out_printf (out, "\tcallback ((%s *)data1", typebase);
919 out_printf (out, "\tv_return = callback ((%s *)data1",
923 print_signal_marsal_args (m);
926 /* FIXME: This code is so fucking ugly it hurts */
927 gboolean take_ownership =
928 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
929 strcmp ((char *)m->gtktypes->data, "BOXED") == 0);
933 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
934 /* hack because glib is braindamaged */
935 set_func = g_strdup ("g_value_set_uint");
937 set_func = g_strdup_printf ("g_value_%s_%s",
940 (char *)m->gtktypes->data);
941 gob_strdown (set_func);
943 out_printf (out, "\n\t%s (return_value, v_return);\n",
948 if (no_gnu || for_cpp /* g++ has a cow with G_GNUC_UNUSED */) {
950 out_printf (out, "\n\treturn_value = NULL;\n");
951 out_printf (out, "\tinvocation_hint = NULL;\n");
954 out_printf (out, "}\n\n");
958 interface_type(const char *if_name)
960 char *rawtype = remove_sep(if_name);
961 char *end = "", *typename;
965 * EEEK! evil, we should have some sort of option
966 * to force this for arbitrary interfaces, since
967 * some are Class and some are Iface. Glib is shite
971 if (strcmp (rawtype, "GtkEditable") == 0
972 || strcmp (rawtype, "GTypePlugin") == 0)
976 /* We'll assume Iface is the standard ending */
980 /* GTK3 doesn't need Iface end */
984 typename = g_strconcat(rawtype, end, (char *)NULL);
991 define_parent_interface_refs(Class *c)
998 out_printf(out, "\n/* parent class interface implementations */\n");
999 for (li = c->interfaces; li != NULL; li = li->next) {
1000 char *name = replace_sep(li->data, '_');
1001 char *type = interface_type(li->data);
1003 out_printf (out, "static %s *%s_parent_iface;\n", type, name);
1014 out_printf(out, "\n");
1016 out_printf(out, "enum {\n");
1017 for(li=c->nodes;li;li=g_list_next(li)) {
1019 if(n->type == METHOD_NODE) {
1020 Method *m = (Method *)n;
1021 if(m->method == SIGNAL_LAST_METHOD ||
1022 m->method == SIGNAL_FIRST_METHOD) {
1023 char *s = g_strdup(m->id);
1025 out_printf(out, "\t%s_SIGNAL,\n", s);
1030 out_printf(out, "\tLAST_SIGNAL\n};\n\n");
1032 if (set_properties > 0 ||
1033 get_properties > 0) {
1034 out_printf(out, "enum {\n\tPROP_0");
1035 for(li=c->nodes;li;li=g_list_next(li)) {
1037 if (n->type == PROPERTY_NODE) {
1038 Property *p = (Property *)n;
1039 char *s = g_strdup (p->name);
1041 out_printf (out, ",\n\tPROP_%s", s);
1043 } else if (n->type == ARGUMENT_NODE) {
1044 Argument *a = (Argument *)n;
1045 char *s = g_strdup(a->name);
1047 out_printf(out, ",\n\tPROP_%s", s);
1051 out_printf(out, "\n};\n\n");
1056 "static guint object_signals[LAST_SIGNAL] = {0};\n\n");
1058 out_printf(out, "/* pointer to the class of our parent */\n");
1059 out_printf(out, "static %sClass *parent_class = NULL;\n", ptypebase);
1060 define_parent_interface_refs(c);
1061 out_printf(out, "\n");
1065 add_interface_methods (Class *c, const char *interface)
1068 gboolean added_line = FALSE;
1070 for (li = c->nodes; li != NULL; li = li->next) {
1072 Method *m = (Method *)n;
1073 if (n->type != METHOD_NODE ||
1074 m->method == OVERRIDE_METHOD ||
1075 m->interface == NULL ||
1076 strcmp (m->interface, interface) != 0)
1079 if (m->line_no > 0) {
1080 out_addline_infile (out, m->line_no);
1082 } else if (m->line_no == 0 &&
1084 out_addline_outfile (out);
1087 out_printf (out, "\tiface->%s = self_%s;\n",
1091 out_addline_outfile (out);
1095 add_interface_inits(Class *c)
1099 if (c->interfaces == NULL)
1102 out_printf(out, "\n");
1104 for (li = c->interfaces; li != NULL; li = li->next) {
1105 char *name = replace_sep(li->data, '_');
1106 char *type = interface_type(li->data);
1108 out_printf(out, "static void\n"
1109 "___%s_init (%s *iface)\n"
1112 add_interface_methods(c, li->data);
1114 out_printf(out, "\t%s_parent_iface\n", name);
1115 out_printf(out, for_cpp ? "\t\t= (%s *)" : "\t\t= ", type);
1116 out_printf(out, "g_type_interface_peek_parent(iface);\n"
1125 add_interface_infos(Class *c, gboolean static_storage)
1129 for (li = c->interfaces; li; li = li->next) {
1130 char *name = replace_sep(li->data, '_');
1131 out_printf(out, "\t%sconst GInterfaceInfo %s_info = {\n"
1132 "\t\t(GInterfaceInitFunc) ___%s_init,\n"
1136 static_storage ? "static " : "",
1141 out_printf(out, "\n");
1145 define_add_interfaces(Class *c)
1152 out_printf(out, "static void ___add_interfaces(GType type)\n{\n");
1153 add_interface_infos(c, TRUE);
1155 for (li = c->interfaces; li; li = li->next) {
1156 char *type = make_pre_macro(li->data, "TYPE");
1157 char *name = replace_sep(li->data, '_');
1159 out_printf(out, "\tg_type_add_interface_static\n"
1170 out_printf(out, "}\n\n");
1174 define_dynamic_add_interfaces(Class *c)
1181 out_printf(out, "static void ___add_interfaces"
1182 "(GTypeModule *type_module, GType type)\n"
1184 add_interface_infos(c, FALSE);
1187 * Hack to work around bug in g_type_module_add_interface,
1188 * which will fail to add an interface to types that derive
1189 * from something that also implements the same interface.
1191 * The actual GType system does not have any such problem,
1192 * and the GTypeModule implementation details relied upon
1193 * here have not changed once since the feature was first
1194 * implemented almost 20 years ago.
1196 out_printf(out, "\tstruct _ModuleInterfaceInfo {\n"
1197 "\t\tgboolean loaded;\n"
1198 "\t\tGType instance_type;\n"
1199 "\t\tGType interface_type;\n"
1200 "\t\tGInterfaceInfo info;\n"
1203 for (li = c->interfaces; li; li = li->next) {
1204 char *type = make_pre_macro(li->data, "TYPE");
1205 char *name = replace_sep(li->data, '_');
1207 out_printf(out, "\n"
1208 "\tmodinfo = g_malloc(sizeof *modinfo);\n"
1209 "\tmodinfo->loaded = TRUE;\n"
1210 "\tmodinfo->instance_type = type;\n"
1211 "\tmodinfo->interface_type = %s;\n"
1212 "\tmodinfo->info = %s_info;\n"
1213 "\tg_type_add_interface_dynamic\n"
1214 "\t\t( modinfo->instance_type\n"
1215 "\t\t, modinfo->interface_type\n"
1216 "\t\t, G_TYPE_PLUGIN(type_module)\n"
1218 "\ttype_module->interface_infos = g_slist_prepend\n"
1219 "\t\t( type_module->interface_infos\n"
1228 out_printf(out, "}\n\n");
1231 static void add_type_info(void)
1233 out_printf(out, "\tstatic const GTypeInfo info = {\n"
1234 "\t\tsizeof (%sClass),\n"
1235 "\t\t(GBaseInitFunc) NULL,\n"
1236 "\t\t(GBaseFinalizeFunc) NULL,\n"
1237 "\t\t(GClassInitFunc) %s_class_init,\n"
1238 "\t\t(GClassFinalizeFunc) NULL,\n"
1239 "\t\tNULL /* class_data */,\n"
1240 "\t\tsizeof (%s),\n"
1241 "\t\t%d /* n_preallocs */,\n"
1242 "\t\t(GInstanceInitFunc) %s_init,\n"
1245 typebase, funcbase, typebase, prealloc, funcbase);
1251 Class *c = (Class *)class;
1253 define_add_interfaces(c);
1255 out_printf(out, "#ifdef G_DEFINE_TYPE_EXTENDED\n\n"
1256 "G_DEFINE_TYPE_EXTENDED(%s, %s, %s,\n"
1257 "\t(GTypeFlags)%s,\n",
1258 typebase, funcbase, pmacrotype,
1259 c->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0");
1262 out_printf(out, "\t___add_interfaces(g_define_type_id);\n");
1264 /* Fallback for GLib < 2.4 */
1265 out_printf(out, ");\n\n"
1267 "GType %s_get_type(void)\n"
1269 "\tstatic GType type = 0;\n",
1274 out_printf(out, "\tif ___GOB_UNLIKELY(type == 0) {\n"
1275 "\t\ttype = g_type_register_static\n"
1279 "\t\t\t, (GTypeFlags)%s\n"
1281 pmacrotype, typebase,
1282 c->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0");
1285 out_printf(out, "\t\t___add_interfaces(type);\n");
1287 out_printf(out, "\t}\n\n"
1294 add_dynamic_get_type(void)
1296 Class *c = (Class *)class;
1298 define_dynamic_add_interfaces(c);
1301 * G_DEFINE_DYNAMIC_TYPE_EXTENDED is usable if available, except for
1302 * some reason it defines an xxx_register_type function with internal
1303 * linkage. This is kind of weird so we have to work around that.
1305 out_printf(out, "#ifdef G_DEFINE_DYNAMIC_TYPE_EXTENDED\n\n"
1306 "static void %s_class_finalize(%sClass *c) { }\n\n"
1307 "#define %s_register_type ___register_type\n",
1308 funcbase, typebase, funcbase);
1310 out_printf(out, "G_DEFINE_DYNAMIC_TYPE_EXTENDED(%s, %s, %s,\n"
1311 "\t(GTypeFlags)%s,\n",
1312 typebase, funcbase, pmacrotype,
1313 c->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0");
1315 if (c->interfaces) {
1316 out_printf(out, "\t___add_interfaces"
1317 "(type_module, %s_type_id);\n", funcbase);
1320 out_printf(out, ");\n"
1321 "#undef %s_register_type\n\n"
1322 "void %s_register_type(GTypeModule *type_module)\n"
1324 "\t___register_type(type_module);\n"
1326 funcbase, funcbase);
1328 /* Fallback for GLib < 2.14 */
1329 out_printf(out, "#else\n\n"
1330 "static GType %s_type_id;\n\n"
1331 "GType %s_get_type(void)\n"
1333 "\treturn %s_type_id;\n"
1335 funcbase, funcbase, funcbase);
1337 out_printf(out, "void %s_register_type(GTypeModule *type_module)\n"
1343 out_printf(out, "\t%s_type_id = g_type_module_register_type\n"
1344 "\t\t( type_module\n"
1348 "\t\t, (GTypeFlags)%s\n"
1350 funcbase, pmacrotype, typebase,
1351 c->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0");
1353 if (c->interfaces) {
1354 out_printf(out, "\t___add_interfaces"
1355 "(type_module, %s_type_id);\n",
1359 out_printf(out, "}\n\n"
1364 add_bonobo_object_get_type(void)
1366 Class *c = (Class *)class;
1368 define_add_interfaces(c);
1370 out_printf (out, "GType %s_get_type(void)\n"
1372 "\tstatic GType type = 0;\n",
1377 out_printf (out, "\tif ___GOB_UNLIKELY(type == 0) {\n"
1378 "\t\ttype = bonobo_type_unique\n"
1379 "\t\t\t( BONOBO_OBJECT_TYPE\n"
1380 "\t\t\t, POA_%s__init, NULL\n"
1381 "\t\t\t, G_STRUCT_OFFSET (%sClass, _epv)\n"
1385 c->bonobo_object_class, typebase, typebase);
1387 if (((Class *)class)->interfaces)
1388 out_printf(out, "\t\t___add_interfaces(type);\n");
1390 out_printf(out, "\t}\n\n"
1396 add_overrides(Class *c, const char *oname,
1397 gboolean did_base_obj)
1403 done = g_hash_table_new (g_str_hash, g_str_equal);
1405 s = g_strdup ("GObject");
1406 g_hash_table_insert (done, s, s);
1408 for (li = c->nodes; li != NULL; li = li->next) {
1411 Method *m = (Method *)n;
1412 if(n->type != METHOD_NODE ||
1413 m->method != OVERRIDE_METHOD)
1416 s = remove_sep(m->otype);
1418 if(g_hash_table_lookup(done, s)) {
1422 g_hash_table_insert(done, s, s);
1424 f = replace_sep(m->otype, '_');
1427 out_printf(out, "\t%sClass *%s_class = (%sClass *)%s;\n",
1432 g_hash_table_foreach (done, (GHFunc)g_free, NULL);
1433 g_hash_table_destroy (done);
1437 make_run_signal_flags(Method *m, gboolean last)
1452 gs = g_string_new(NULL);
1455 g_string_assign(gs, "G_SIGNAL_RUN_LAST");
1457 g_string_assign(gs, "G_SIGNAL_RUN_FIRST");
1459 if(m->scope == PUBLIC_SCOPE)
1460 g_string_append(gs, " | G_SIGNAL_ACTION");
1462 for(li = m->flags; li; li = li->next) {
1463 char *flag = li->data;
1465 for(i=0;flags[i];i++) {
1466 if(strcmp(flags[i], flag)==0)
1469 /* if we haven't found it in our list */
1471 error_printf(GOB_WARN, m->line_no,
1472 "Unknown flag '%s' used, "
1473 "perhaps it was misspelled",
1476 g_string_sprintfa(gs, " | G_SIGNAL_%s", flag);
1480 char *ret = gs->str;
1481 g_string_free(gs, FALSE);
1488 add_signals(Class *c)
1492 out_printf(out, "\n");
1493 for(li=c->nodes;li;li=g_list_next(li)) {
1495 char *mar, *sig, *flags;
1496 gboolean is_none, last = FALSE;
1497 Method *m = (Method *)n;
1499 if(n->type != METHOD_NODE ||
1500 (m->method != SIGNAL_FIRST_METHOD &&
1501 m->method != SIGNAL_LAST_METHOD))
1504 if(m->method == SIGNAL_FIRST_METHOD)
1509 if(g_hash_table_lookup(marsh, m))
1510 mar = g_strconcat("___marshal_",
1511 (char *)g_hash_table_lookup(marsh, m),
1514 mar = g_strdup("g_cclosure_marshal_VOID__VOID");
1516 is_none = (strcmp(m->gtktypes->next->data, "NONE")==0);
1518 sig = g_strdup (m->id);
1520 flags = make_run_signal_flags (m, last);
1521 out_printf (out, "\tobject_signals[%s_SIGNAL] =\n"
1522 "\t\tg_signal_new (%s,\n"
1523 "\t\t\tG_TYPE_FROM_CLASS (g_object_class),\n"
1524 "\t\t\t(GSignalFlags)(%s),\n"
1525 "\t\t\tG_STRUCT_OFFSET (%sClass, %s),\n"
1526 "\t\t\tNULL, NULL,\n"
1528 "\t\t\tG_TYPE_%s, %d",
1529 sig, m->signal_name /*m->id* if not given signal_name*/,
1531 typebase, m->id, mar,
1532 (char *)m->gtktypes->data,
1533 is_none ? 0 : g_list_length(m->gtktypes->next));
1541 for(l = m->gtktypes->next; l != NULL; l = l->next) {
1542 char *str = l->data;
1543 if (strncmp (str, "BOXED_", 6) == 0)
1544 t = g_strdup (&(str[6]));
1546 t = g_strconcat ("G_TYPE_", str, NULL);
1547 out_printf (out, ",\n\t\t\t%s", t);
1552 out_printf(out, ");\n");
1554 if(strcmp(m->gtktypes->data, "NONE") != 0 ||
1557 out_printf(out, "\tif ___GOB_UNLIKELY(");
1558 if(strcmp(m->gtktypes->data, "NONE") != 0) {
1559 out_printf(out, "sizeof(");
1560 print_type(out, m->mtype, FALSE);
1561 out_printf(out, "%s",
1563 m->mtype->postfix : "");
1564 out_printf(out, ") != sizeof(%s) || ",
1565 get_cast(m->gtktypes->data, FALSE));
1568 for(al = m->args->next, gl = m->gtktypes->next;
1569 al != NULL && gl != NULL;
1570 al = al->next, gl = gl->next) {
1571 FuncArg *arg = al->data;
1572 char *gtkarg = gl->data;
1574 out_printf(out, "sizeof(");
1575 print_type(out, arg->atype, FALSE);
1576 out_printf(out, "%s",
1577 arg->atype->postfix ?
1578 arg->atype->postfix : "");
1579 out_printf(out, ") != sizeof(%s) || ",
1580 get_cast(gtkarg, FALSE));
1584 "parent_class == NULL /* avoid warning */");
1586 out_printf(out, ") {\n"
1587 "\t\tg_error(\"%s line %d: Type mismatch "
1588 "of \\\"%s\\\" signal signature\");\n"
1590 filename, m->line_no, m->id);
1597 set_def_handlers(Class *c, const char *oname)
1600 gboolean set_line = FALSE;
1602 out_printf(out, "\n");
1603 for(li = c->nodes; li; li = g_list_next(li)) {
1605 Method *m = (Method *)n;
1607 if(n->type != METHOD_NODE ||
1608 (m->method != SIGNAL_FIRST_METHOD &&
1609 m->method != SIGNAL_LAST_METHOD &&
1610 m->method != VIRTUAL_METHOD &&
1611 m->method != OVERRIDE_METHOD))
1614 if(m->line_no > 0 && m->cbuf) {
1615 out_addline_infile(out, m->line_no);
1617 } else if(set_line) {
1618 out_addline_outfile(out);
1623 if (m->method == OVERRIDE_METHOD) {
1625 s = replace_sep (m->otype, '_');
1629 dispose_handler != NULL &&
1630 strcmp (m->id, "dispose") == 0)
1631 out_printf (out, "\tg_object_class->dispose "
1633 else if (need_finalize &&
1635 strcmp(m->id, "finalize") == 0)
1637 "\tg_object_class->finalize = ___finalize;\n");
1638 else if (m->cbuf != NULL)
1640 "\t%s_class->%s = ___%x_%s_%s;\n",
1641 s, m->id, (guint)m->unique_id,
1644 out_printf(out, "\t%s_class->%s = NULL;\n",
1648 out_printf(out, "\t%s->%s = ___real_%s_%s;\n",
1652 out_printf(out, "\t%s->%s = NULL;\n",
1657 out_addline_outfile(out);
1661 make_argument (Argument *a)
1666 char *argflags[] = {
1674 flags = g_string_new ("(GParamFlags)(");
1676 if(a->get && a->set)
1677 g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
1679 g_string_append (flags, "G_PARAM_READABLE");
1681 g_string_append (flags, "G_PARAM_WRITABLE");
1683 g_assert(a->get || a->set);
1685 for (l = a->flags; l != NULL; l = l->next) {
1686 char *flag = l->data;
1688 if(strcmp (flag, "READABLE") == 0 ||
1689 strcmp (flag, "WRITABLE") == 0) {
1690 error_print(GOB_WARN, a->line_no,
1692 "WRITABLE argument flags are "
1693 "set automatically");
1696 for(i = 0; argflags[i]; i++) {
1697 if(strcmp(argflags[i], flag)==0)
1700 g_string_sprintfa(flags, " | %s%s", argflags[i] ? "G_PARAM_" : "", flag);
1703 g_string_append (flags, ")");
1705 s = g_strdup(a->name);
1707 if (!strcmp (a->gtktype, "ENUM"))
1708 out_printf(out, "\tparam_spec = g_param_spec_enum (\"%s\", NULL, NULL,\n"
1709 "\t\tG_TYPE_ENUM, 0,\n"
1711 a->name, flags->str);
1712 if (!strcmp (a->gtktype, "FLAGS"))
1713 out_printf(out, "\tparam_spec = g_param_spec_flags (\"%s\", NULL, NULL,\n"
1714 "\t\tG_TYPE_FLAGS, 0,\n"
1716 a->name, flags->str);
1717 else if (!strcmp (a->gtktype, "OBJECT"))
1718 out_printf(out, "\tparam_spec = g_param_spec_object (\"%s\", NULL, NULL,\n"
1719 "\t\tG_TYPE_OBJECT,\n"
1721 a->name, flags->str);
1722 else if (!strcmp (a->gtktype, "STRING"))
1723 out_printf(out, "\tparam_spec = g_param_spec_string (\"%s\", NULL, NULL,\n"
1726 a->name, flags->str);
1727 else if (!strcmp (a->gtktype, "INT"))
1728 out_printf(out, "\tparam_spec = g_param_spec_int (\"%s\", NULL, NULL,\n"
1729 "\t\tG_MININT, G_MAXINT,\n"
1732 a->name, flags->str);
1733 else if (!strcmp (a->gtktype, "UINT"))
1734 out_printf(out, "\tparam_spec = g_param_spec_uint (\"%s\", NULL, NULL,\n"
1735 "\t\t0, G_MAXUINT,\n"
1738 a->name, flags->str);
1739 else if (!strcmp (a->gtktype, "INT"))
1740 out_printf(out, "\tparam_spec = g_param_spec_int (\"%s\", NULL, NULL,\n"
1741 "\t\tG_MININT, G_MAXINT,\n"
1744 a->name, flags->str);
1745 else if (!strcmp (a->gtktype, "CHAR"))
1746 out_printf(out, "\tparam_spec = g_param_spec_char (\"%s\", NULL, NULL,\n"
1750 a->name, flags->str);
1751 else if (!strcmp (a->gtktype, "UCHAR"))
1752 out_printf(out, "\tparam_spec = g_param_spec_uchar (\"%s\", NULL, NULL,\n"
1756 a->name, flags->str);
1757 else if (!strcmp (a->gtktype, "BOOL") ||
1758 !strcmp (a->gtktype, "BOOLEAN"))
1759 out_printf(out, "\tparam_spec = g_param_spec_boolean (\"%s\", NULL, NULL,\n"
1762 a->name, flags->str);
1763 else if (!strcmp (a->gtktype, "LONG"))
1764 out_printf(out, "\tparam_spec = g_param_spec_long (\"%s\", NULL, NULL,\n"
1765 "\t\tG_MINLONG, G_MAXLONG,\n"
1768 a->name, flags->str);
1769 else if (!strcmp (a->gtktype, "ULONG"))
1770 out_printf(out, "\tparam_spec = g_param_spec_ulong (\"%s\", NULL, NULL,\n"
1771 "\t\t0, G_MAXULONG,\n"
1774 a->name, flags->str);
1775 else if (!strcmp (a->gtktype, "INT64"))
1776 out_printf(out, "\tparam_spec = g_param_spec_int64 (\"%s\", NULL, NULL,\n"
1777 "\t\tG_MININT64, G_MAXINT64,\n"
1780 a->name, flags->str);
1781 else if (!strcmp (a->gtktype, "UINT64"))
1782 out_printf(out, "\tparam_spec = g_param_spec_uint64 (\"%s\", NULL, NULL,\n"
1783 "\t\t0, G_MAXUINT64,\n"
1786 a->name, flags->str);
1787 else if (!strcmp (a->gtktype, "FLOAT"))
1788 out_printf(out, "\tparam_spec = g_param_spec_float (\"%s\", NULL, NULL,\n"
1789 "\t\t-G_MAXFLOAT, G_MAXFLOAT,\n"
1792 a->name, flags->str);
1793 else if (!strcmp (a->gtktype, "DOUBLE"))
1794 out_printf(out, "\tparam_spec = g_param_spec_double (\"%s\", NULL, NULL,\n"
1795 "\t\t-G_MAXDOUBLE, G_MAXDOUBLE,\n"
1798 a->name, flags->str);
1799 else if (!strcmp (a->gtktype, "POINTER"))
1800 out_printf(out, "\tparam_spec = g_param_spec_pointer (\"%s\", NULL, NULL,\n"
1802 a->name, flags->str);
1804 error_printf (GOB_ERROR, a->line_no,
1805 "%s type is not supported for arguments, try using properties",
1808 out_printf(out, "\tg_object_class_install_property (g_object_class,\n"
1809 "\t\tPROP_%s, param_spec);\n", s);
1813 g_string_free(flags, TRUE);
1816 #define value_for_print(str, alt) (str != NULL ? str : alt)
1819 make_property (Property *p)
1823 if (p->get == NULL && p->set == NULL) {
1824 error_print (GOB_ERROR, p->line_no,
1825 "Property has no getter nor setter");
1829 if (p->flags != NULL)
1830 error_print (GOB_WARN, p->line_no,
1831 "Overridden property, flags ignored");
1832 if (p->nick != NULL)
1833 error_print (GOB_WARN, p->line_no,
1834 "Overridden property, nick ignored");
1835 if (p->blurb != NULL)
1836 error_print (GOB_WARN, p->line_no,
1837 "Overridden property, blurb ignored");
1838 if (p->minimum != NULL)
1839 error_print (GOB_WARN, p->line_no,
1840 "Overridden property, minimum ignored");
1841 if (p->maximum != NULL)
1842 error_print (GOB_WARN, p->line_no,
1843 "Overridden property, maximum ignored");
1844 if (p->default_value != NULL)
1845 error_print (GOB_WARN, p->line_no,
1846 "Overridden property, default_value ignored");
1848 s = g_strdup (p->name);
1850 out_printf (out, "\tg_object_class_override_property (g_object_class,\n"
1852 "\t\t\"%s\");\n", s, value_for_print (p->canonical_name, p->name) );
1857 char *argflags[] = {
1865 flags = g_string_new ("(GParamFlags)(");
1867 if (p->get != NULL && p->set != NULL)
1868 g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
1869 else if (p->get != NULL)
1870 g_string_append (flags, "G_PARAM_READABLE");
1872 g_string_append (flags, "G_PARAM_WRITABLE");
1875 for (l = p->flags; l != NULL; l = l->next) {
1876 char *flag = l->data;
1878 if(strcmp (flag, "READABLE") == 0 ||
1879 strcmp (flag, "WRITABLE") == 0) {
1880 error_print(GOB_WARN, p->line_no,
1882 "WRITABLE argument flags are "
1883 "set automatically");
1886 for(i = 0; argflags[i]; i++) {
1887 if(strcmp(argflags[i], flag)==0)
1890 g_string_sprintfa(flags, " | %s%s", argflags[i] ? "G_PARAM_" : "", flag);
1893 g_string_append (flags, ")");
1895 if (strcmp (p->gtktype, "CHAR") == 0) {
1896 out_printf (out, "\tparam_spec = g_param_spec_char\n"
1897 "\t\t(\"%s\" /* name */,\n"
1898 "\t\t %s /* nick */,\n"
1899 "\t\t %s /* blurb */,\n"
1900 "\t\t %s /* minimum */,\n"
1901 "\t\t %s /* maximum */,\n"
1902 "\t\t %s /* default_value */,\n"
1904 value_for_print (p->canonical_name, p->name),
1905 value_for_print (p->nick, "NULL"),
1906 value_for_print (p->blurb, "NULL"),
1907 value_for_print (p->minimum, "-128"),
1908 value_for_print (p->maximum, "127"),
1909 value_for_print (p->default_value, "0"),
1911 } else if (strcmp (p->gtktype, "UCHAR") == 0) {
1912 out_printf (out, "\tparam_spec = g_param_spec_uchar\n"
1913 "\t\t(\"%s\" /* name */,\n"
1914 "\t\t %s /* nick */,\n"
1915 "\t\t %s /* blurb */,\n"
1916 "\t\t %s /* minimum */,\n"
1917 "\t\t %s /* maximum */,\n"
1918 "\t\t %s /* default_value */,\n"
1920 value_for_print (p->canonical_name, p->name),
1921 value_for_print (p->nick, "NULL"),
1922 value_for_print (p->blurb, "NULL"),
1923 value_for_print (p->minimum, "0"),
1924 value_for_print (p->maximum, "0xFF"),
1925 value_for_print (p->default_value, "0"),
1927 } else if (strcmp (p->gtktype, "BOOLEAN") == 0) {
1928 out_printf (out, "\tparam_spec = g_param_spec_boolean\n"
1929 "\t\t(\"%s\" /* name */,\n"
1930 "\t\t %s /* nick */,\n"
1931 "\t\t %s /* blurb */,\n"
1932 "\t\t %s /* default_value */,\n"
1934 value_for_print (p->canonical_name, p->name),
1935 value_for_print (p->nick, "NULL"),
1936 value_for_print (p->blurb, "NULL"),
1937 value_for_print (p->default_value, "FALSE"),
1939 } else if (strcmp (p->gtktype, "INT") == 0) {
1940 out_printf (out, "\tparam_spec = g_param_spec_int\n"
1941 "\t\t(\"%s\" /* name */,\n"
1942 "\t\t %s /* nick */,\n"
1943 "\t\t %s /* blurb */,\n"
1944 "\t\t %s /* minimum */,\n"
1945 "\t\t %s /* maximum */,\n"
1946 "\t\t %s /* default_value */,\n"
1948 value_for_print (p->canonical_name, p->name),
1949 value_for_print (p->nick, "NULL"),
1950 value_for_print (p->blurb, "NULL"),
1951 value_for_print (p->minimum, "G_MININT"),
1952 value_for_print (p->maximum, "G_MAXINT"),
1953 value_for_print (p->default_value, "0"),
1955 } else if (strcmp (p->gtktype, "UINT") == 0) {
1956 out_printf (out, "\tparam_spec = g_param_spec_uint\n"
1957 "\t\t(\"%s\" /* name */,\n"
1958 "\t\t %s /* nick */,\n"
1959 "\t\t %s /* blurb */,\n"
1960 "\t\t %s /* minimum */,\n"
1961 "\t\t %s /* maximum */,\n"
1962 "\t\t %s /* default_value */,\n"
1964 value_for_print (p->canonical_name, p->name),
1965 value_for_print (p->nick, "NULL"),
1966 value_for_print (p->blurb, "NULL"),
1967 value_for_print (p->minimum, "0"),
1968 value_for_print (p->maximum, "G_MAXUINT"),
1969 value_for_print (p->default_value, "0"),
1971 } else if (strcmp (p->gtktype, "LONG") == 0) {
1972 out_printf (out, "\tparam_spec = g_param_spec_long\n"
1973 "\t\t(\"%s\" /* name */,\n"
1974 "\t\t %s /* nick */,\n"
1975 "\t\t %s /* blurb */,\n"
1976 "\t\t %s /* minimum */,\n"
1977 "\t\t %s /* maximum */,\n"
1978 "\t\t %s /* default_value */,\n"
1980 value_for_print (p->canonical_name, p->name),
1981 value_for_print (p->nick, "NULL"),
1982 value_for_print (p->blurb, "NULL"),
1983 value_for_print (p->minimum, "G_MINLONG"),
1984 value_for_print (p->maximum, "G_MAXLONG"),
1985 value_for_print (p->default_value, "0"),
1987 } else if (strcmp (p->gtktype, "ULONG") == 0) {
1988 out_printf (out, "\tparam_spec = g_param_spec_ulong\n"
1989 "\t\t(\"%s\" /* name */,\n"
1990 "\t\t %s /* nick */,\n"
1991 "\t\t %s /* blurb */,\n"
1992 "\t\t %s /* minimum */,\n"
1993 "\t\t %s /* maximum */,\n"
1994 "\t\t %s /* default_value */,\n"
1996 value_for_print (p->canonical_name, p->name),
1997 value_for_print (p->nick, "NULL"),
1998 value_for_print (p->blurb, "NULL"),
1999 value_for_print (p->minimum, "0"),
2000 value_for_print (p->maximum, "G_MAXULONG"),
2001 value_for_print (p->default_value, "0"),
2003 } else if (strcmp (p->gtktype, "INT64") == 0) {
2004 out_printf (out, "\tparam_spec = g_param_spec_int64\n"
2005 "\t\t(\"%s\" /* name */,\n"
2006 "\t\t %s /* nick */,\n"
2007 "\t\t %s /* blurb */,\n"
2008 "\t\t %s /* minimum */,\n"
2009 "\t\t %s /* maximum */,\n"
2010 "\t\t %s /* default_value */,\n"
2012 value_for_print (p->canonical_name, p->name),
2013 value_for_print (p->nick, "NULL"),
2014 value_for_print (p->blurb, "NULL"),
2015 value_for_print (p->minimum, "G_MININT64"),
2016 value_for_print (p->maximum, "G_MAXINT64"),
2017 value_for_print (p->default_value, "0"),
2019 } else if (strcmp (p->gtktype, "UINT64") == 0) {
2020 out_printf (out, "\tparam_spec = g_param_spec_uint64\n"
2021 "\t\t(\"%s\" /* name */,\n"
2022 "\t\t %s /* nick */,\n"
2023 "\t\t %s /* blurb */,\n"
2024 "\t\t %s /* minimum */,\n"
2025 "\t\t %s /* maximum */,\n"
2026 "\t\t %s /* default_value */,\n"
2028 value_for_print (p->canonical_name, p->name),
2029 value_for_print (p->nick, "NULL"),
2030 value_for_print (p->blurb, "NULL"),
2031 value_for_print (p->minimum, "0"),
2032 value_for_print (p->maximum, "G_MAXUINT64"),
2033 value_for_print (p->default_value, "0"),
2035 } else if (strcmp (p->gtktype, "UNICHAR") == 0) {
2036 out_printf (out, "\tparam_spec = g_param_spec_unichar\n"
2037 "\t\t(\"%s\" /* name */,\n"
2038 "\t\t %s /* nick */,\n"
2039 "\t\t %s /* blurb */,\n"
2040 "\t\t %s /* default_value */,\n"
2042 value_for_print (p->canonical_name, p->name),
2043 value_for_print (p->nick, "NULL"),
2044 value_for_print (p->blurb, "NULL"),
2045 value_for_print (p->default_value, "0"),
2047 } else if (strcmp (p->gtktype, "ENUM") == 0) {
2048 char *type = make_me_type (p->extra_gtktype,
2050 out_printf (out, "\tparam_spec = g_param_spec_enum\n"
2051 "\t\t(\"%s\" /* name */,\n"
2052 "\t\t %s /* nick */,\n"
2053 "\t\t %s /* blurb */,\n"
2054 "\t\t %s /* enum_type */,\n"
2055 "\t\t %s /* default_value */,\n"
2057 value_for_print (p->canonical_name, p->name),
2058 value_for_print (p->nick, "NULL"),
2059 value_for_print (p->blurb, "NULL"),
2061 value_for_print (p->default_value, "0"),
2064 } else if (strcmp (p->gtktype, "FLAGS") == 0) {
2065 char *type = make_me_type (p->extra_gtktype,
2067 out_printf (out, "\tparam_spec = g_param_spec_flags\n"
2068 "\t\t(\"%s\" /* name */,\n"
2069 "\t\t %s /* nick */,\n"
2070 "\t\t %s /* blurb */,\n"
2071 "\t\t %s /* flags_type */,\n"
2072 "\t\t %s /* default_value */,\n"
2074 value_for_print (p->canonical_name, p->name),
2075 value_for_print (p->nick, "NULL"),
2076 value_for_print (p->blurb, "NULL"),
2078 value_for_print (p->default_value, "0"),
2081 } else if (strcmp (p->gtktype, "FLOAT") == 0) {
2082 out_printf (out, "\tparam_spec = g_param_spec_float\n"
2083 "\t\t(\"%s\" /* name */,\n"
2084 "\t\t %s /* nick */,\n"
2085 "\t\t %s /* blurb */,\n"
2086 "\t\t %s /* minimum */,\n"
2087 "\t\t %s /* maximum */,\n"
2088 "\t\t %s /* default_value */,\n"
2090 value_for_print (p->canonical_name, p->name),
2091 value_for_print (p->nick, "NULL"),
2092 value_for_print (p->blurb, "NULL"),
2093 value_for_print (p->minimum, "-G_MAXFLOAT"),
2094 value_for_print (p->maximum, "G_MAXFLOAT"),
2095 value_for_print (p->default_value, "0.0"),
2097 } else if (strcmp (p->gtktype, "DOUBLE") == 0) {
2098 out_printf (out, "\tparam_spec = g_param_spec_double\n"
2099 "\t\t(\"%s\" /* name */,\n"
2100 "\t\t %s /* nick */,\n"
2101 "\t\t %s /* blurb */,\n"
2102 "\t\t %s /* minimum */,\n"
2103 "\t\t %s /* maximum */,\n"
2104 "\t\t %s /* default_value */,\n"
2106 value_for_print (p->canonical_name, p->name),
2107 value_for_print (p->nick, "NULL"),
2108 value_for_print (p->blurb, "NULL"),
2109 value_for_print (p->minimum, "-G_MAXDOUBLE"),
2110 value_for_print (p->maximum, "G_MAXDOUBLE"),
2111 value_for_print (p->default_value, "0.0"),
2113 } else if (strcmp (p->gtktype, "STRING") == 0) {
2114 out_printf (out, "\tparam_spec = g_param_spec_string\n"
2115 "\t\t(\"%s\" /* name */,\n"
2116 "\t\t %s /* nick */,\n"
2117 "\t\t %s /* blurb */,\n"
2118 "\t\t %s /* default_value */,\n"
2120 value_for_print (p->canonical_name, p->name),
2121 value_for_print (p->nick, "NULL"),
2122 value_for_print (p->blurb, "NULL"),
2123 value_for_print (p->default_value, "NULL"),
2125 } else if (strcmp (p->gtktype, "PARAM") == 0) {
2126 char *type = make_me_type (p->extra_gtktype,
2128 out_printf (out, "\tparam_spec = g_param_spec_param\n"
2129 "\t\t(\"%s\" /* name */,\n"
2130 "\t\t %s /* nick */,\n"
2131 "\t\t %s /* blurb */,\n"
2132 "\t\t %s /* param_type */,\n"
2134 value_for_print (p->canonical_name, p->name),
2135 value_for_print (p->nick, "NULL"),
2136 value_for_print (p->blurb, "NULL"),
2140 } else if (strcmp (p->gtktype, "BOXED") == 0) {
2141 char *type = make_me_type (p->extra_gtktype,
2143 out_printf (out, "\tparam_spec = g_param_spec_boxed\n"
2144 "\t\t(\"%s\" /* name */,\n"
2145 "\t\t %s /* nick */,\n"
2146 "\t\t %s /* blurb */,\n"
2147 "\t\t %s /* boxed_type */,\n"
2149 value_for_print (p->canonical_name, p->name),
2150 value_for_print (p->nick, "NULL"),
2151 value_for_print (p->blurb, "NULL"),
2155 } else if (strcmp (p->gtktype, "POINTER") == 0) {
2156 out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
2157 "\t\t(\"%s\" /* name */,\n"
2158 "\t\t %s /* nick */,\n"
2159 "\t\t %s /* blurb */,\n"
2161 value_for_print (p->canonical_name, p->name),
2162 value_for_print (p->nick, "NULL"),
2163 value_for_print (p->blurb, "NULL"),
2165 /* FIXME: VALUE_ARRAY */
2166 } else if (strcmp (p->gtktype, "CLOSURE") == 0) {
2167 out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
2168 "\t\t(\"%s\" /* name */,\n"
2169 "\t\t %s /* nick */,\n"
2170 "\t\t %s /* blurb */,\n"
2172 value_for_print (p->canonical_name, p->name),
2173 value_for_print (p->nick, "NULL"),
2174 value_for_print (p->blurb, "NULL"),
2176 } else if (strcmp (p->gtktype, "OBJECT") == 0) {
2177 char *type = make_me_type (p->extra_gtktype,
2179 out_printf (out, "\tparam_spec = g_param_spec_object\n"
2180 "\t\t(\"%s\" /* name */,\n"
2181 "\t\t %s /* nick */,\n"
2182 "\t\t %s /* blurb */,\n"
2183 "\t\t %s /* object_type */,\n"
2185 value_for_print (p->canonical_name, p->name),
2186 value_for_print (p->nick, "NULL"),
2187 value_for_print (p->blurb, "NULL"),
2192 error_printf (GOB_ERROR, p->line_no,
2193 "%s type is not supported by properties",
2197 s = g_strdup (p->name);
2199 out_printf (out, "\tg_object_class_install_property (g_object_class,\n"
2201 "\t\tparam_spec);\n", s);
2204 g_string_free (flags, TRUE);
2209 make_arguments(Class *c)
2212 if (get_properties > 0)
2213 out_printf(out, "\tg_object_class->get_property = ___object_get_property;\n");
2214 if (set_properties > 0)
2215 out_printf(out, "\tg_object_class->set_property = ___object_set_property;\n");
2216 out_printf (out, " {\n");
2217 for (li = c->nodes; li != NULL; li = li->next) {
2219 if ((n->type == PROPERTY_NODE && ! ((Property *) n)->override)
2220 || n->type == ARGUMENT_NODE) {
2221 out_printf(out, "\tGParamSpec *param_spec;\n\n");
2226 for (li = c->nodes; li != NULL; li = li->next) {
2228 if (n->type == PROPERTY_NODE)
2229 make_property ((Property *)n);
2230 else if (n->type == ARGUMENT_NODE)
2231 make_argument ((Argument *)n);
2233 out_printf(out, " }\n");
2237 print_initializer(Method *m, Variable *v)
2244 if(v->initializer == NULL)
2247 if(v->scope == PRIVATE_SCOPE)
2248 root = g_strconcat(((FuncArg *)m->args->data)->name,
2251 root = g_strdup(((FuncArg *)m->args->data)->name);
2253 if(v->initializer_line > 0)
2254 out_addline_infile(out, v->initializer_line);
2256 if (v->initializer_simple)
2257 out_printf(out, "\t%s->%s = %s;\n",
2258 root, v->id, v->initializer);
2259 else if (strcmp(v->id, "_glade_xml") == 0)
2260 /* This is OK, this v->initializer string is set internally
2261 and it will eat exactly one string! */
2262 out_printf(out,v->initializer, ((FuncArg *)m->args->data)->name);
2264 out_printf(out, "%s", v->initializer);
2266 if(v->initializer_line > 0)
2267 out_addline_outfile(out);
2273 print_glade_widget(Method *m, Variable *v)
2278 if(!v->glade_widget)
2281 if(v->scope == PRIVATE_SCOPE)
2282 root = g_strconcat(((FuncArg *)m->args->data)->name,
2285 root = g_strdup(((FuncArg *)m->args->data)->name);
2287 cast = get_type(v->vtype, FALSE);
2288 out_printf(out, "\t%s->%s = (%s)glade_xml_get_widget(%s->_glade_xml, \"%s\");\n",
2289 root, v->id, cast, root, v->id);
2295 print_destructor (Variable *v)
2299 if(v->destructor == NULL)
2302 if(v->scope == PRIVATE_SCOPE)
2303 root = "self->_priv";
2307 if(v->destructor_simple) {
2308 if(v->destructor_line > 0)
2309 out_addline_infile(out, v->destructor_line);
2312 out_printf(out, "\tif(%s->%s) { "
2313 "(reinterpret_cast<void (*)(void *)>(%s)) ((gpointer)%s->%s); "
2314 "%s->%s = NULL; }\n",
2315 root, v->id, v->destructor, root, v->id,
2318 out_printf(out, "\tif(%s->%s) { "
2319 "%s ((gpointer) %s->%s); "
2320 "%s->%s = NULL; }\n",
2321 root, v->id, v->destructor, root, v->id,
2325 if(v->destructor_line > 0)
2326 out_addline_outfile(out);
2328 out_printf(out, "#define %s (%s->%s)\n", v->id, root, v->id);
2329 out_printf(out, "#define VAR %s\n", v->id);
2330 out_printf(out, "\t{\n");
2331 if(v->destructor_line > 0)
2332 out_addline_infile(out, v->destructor_line);
2334 out_printf(out, "\t%s}\n", v->destructor);
2336 if(v->destructor_line > 0)
2337 out_addline_outfile(out);
2338 out_printf(out, "\tmemset(&(%s), 0, sizeof(%s));\n",
2340 out_printf(out, "#undef VAR\n");
2341 out_printf(out, "#undef %s\n", v->id);
2346 add_constructor (Class *c)
2348 out_printf(out, "\nstatic GObject *\n"
2349 "___constructor (GType type, guint n_construct_properties, GObjectConstructParam *construct_properties)\n"
2352 "#define __GOB_FUNCTION__ \"%s::constructor\"\n",
2355 out_printf(out, "\tGObject *obj_self;\n");
2356 out_printf(out, "\t%s *self;\n", typebase);
2358 out_printf(out, "\tobj_self = G_OBJECT_CLASS (parent_class)->constructor (type, n_construct_properties, construct_properties);\n");
2359 out_printf(out, "\tself = %s (obj_self);\n", macrobase);
2361 if (user_constructor->line_no > 0)
2362 out_addline_infile (out, user_constructor->line_no);
2363 out_printf (out, "\t%s_constructor (self);\n", funcbase);
2364 if (user_constructor->line_no > 0)
2365 out_addline_outfile (out);
2367 out_printf(out, "\treturn obj_self;\n");
2368 out_printf(out, "}\n"
2369 "#undef __GOB_FUNCTION__\n\n");
2373 print_unreftors (Class *c)
2376 for(li = ((Class *)class)->nodes;
2380 Variable *v = (Variable *)n;
2381 if (n->type == VARIABLE_NODE &&
2382 v->scope != CLASS_SCOPE &&
2383 v->destructor_unref)
2384 print_destructor (v);
2389 add_dispose (Class *c)
2391 out_printf(out, "\nstatic void\n"
2392 "___dispose (GObject *obj_self)\n"
2395 "#define __GOB_FUNCTION__ \"%s::dispose\"\n",
2398 if (unreftors > 0 || user_dispose_method != NULL) {
2399 out_printf (out, "\t%s *self%s = %s (obj_self);\n",
2401 ! no_gnu ? " G_GNUC_UNUSED" : "",
2405 if (dispose_handler != NULL) {
2406 if (unreftors > 0) {
2407 print_unreftors (c);
2410 /* so we get possible bad argument warning */
2411 if (dispose_handler->line_no > 0)
2412 out_addline_infile (out, dispose_handler->line_no);
2413 out_printf (out, "\t___%x_%s_dispose(obj_self);\n",
2414 (guint)dispose_handler->unique_id, funcbase);
2415 if (dispose_handler->line_no > 0)
2416 out_addline_outfile (out);
2418 if (user_dispose_method != NULL) {
2419 if (user_dispose_method->line_no > 0)
2420 out_addline_infile (out, user_dispose_method->line_no);
2421 out_printf (out, "\t%s_dispose (self);\n", funcbase);
2422 if (user_dispose_method->line_no > 0)
2423 out_addline_outfile (out);
2426 if (unreftors > 0) {
2427 print_unreftors (c);
2431 "\tif (G_OBJECT_CLASS (parent_class)->dispose) \\\n"
2432 "\t\t(* G_OBJECT_CLASS (parent_class)->dispose) (obj_self);\n");
2435 out_printf(out, "}\n"
2436 "#undef __GOB_FUNCTION__\n\n");
2440 print_destructors (Class *c)
2443 for (li = ((Class *)class)->nodes;
2447 Variable *v = (Variable *)n;
2448 if (n->type == VARIABLE_NODE &&
2449 v->scope != CLASS_SCOPE &&
2450 ! v->destructor_unref)
2451 print_destructor (v);
2456 add_finalize (Class *c)
2460 "___finalize(GObject *obj_self)\n"
2463 "#define __GOB_FUNCTION__ \"%s::finalize\"\n",
2468 user_finalize_method != NULL) {
2469 const char *unused = "";
2471 unused = " G_GNUC_UNUSED";
2472 out_printf(out, "\t%s *self%s = %s (obj_self);\n",
2473 typebase, unused, macrobase);
2476 const char *unused = "";
2478 unused = " G_GNUC_UNUSED";
2479 out_printf(out, "\tgpointer priv%s = self->_priv;\n",
2483 if(finalize_handler) {
2484 if (destructors > 0) {
2485 print_destructors (c);
2488 /* so we get possible bad argument warning */
2489 if(finalize_handler->line_no > 0)
2490 out_addline_infile(out, finalize_handler->line_no);
2491 out_printf(out, "\t___%x_%s_finalize(obj_self);\n",
2492 (guint)finalize_handler->unique_id, funcbase);
2493 if(finalize_handler->line_no > 0)
2494 out_addline_outfile(out);
2496 if (user_finalize_method != NULL) {
2497 if (user_finalize_method->line_no > 0)
2498 out_addline_infile (out, user_finalize_method->line_no);
2499 out_printf (out, "\t%s_finalize (self);\n", funcbase);
2500 if (user_finalize_method->line_no > 0)
2501 out_addline_outfile (out);
2504 if (destructors > 0) {
2505 print_destructors (c);
2509 "\tif(G_OBJECT_CLASS(parent_class)->finalize) \\\n"
2510 "\t\t(* G_OBJECT_CLASS(parent_class)->finalize)(obj_self);\n");
2513 out_printf(out, "}\n"
2514 "#undef __GOB_FUNCTION__\n\n");
2518 make_bonobo_object_epv (Class *c, const char *classname)
2521 gboolean added_line = FALSE;
2523 for (li = c->nodes; li != NULL; li = li->next) {
2525 Method *m = (Method *)n;
2526 if(n->type != METHOD_NODE ||
2527 m->method == OVERRIDE_METHOD)
2530 if (m->bonobo_object_func) {
2531 if(m->line_no > 0) {
2532 out_addline_infile(out, m->line_no);
2534 } else if (m->line_no == 0 &&
2536 out_addline_outfile(out);
2539 out_printf (out, "\t%s->_epv.%s = self_%s;\n",
2540 classname, m->id, m->id);
2544 out_addline_outfile(out);
2550 const char *unused = "";
2554 unused = " G_GNUC_UNUSED";
2556 for(li=c->nodes;li;li=g_list_next(li)) {
2560 if(n->type != METHOD_NODE)
2563 if(m->method == INIT_METHOD) {
2565 out_addline_infile(out, m->line_no);
2566 print_method(out, "static ", "\n", "", " ", "", "\n",
2567 m, FALSE, FALSE, FALSE, TRUE, TRUE,
2569 out_printf(out, "{\n");
2571 out_addline_outfile(out);
2573 "#define __GOB_FUNCTION__ \"%s::init\"\n",
2576 out_printf(out, "\t%s->_priv = "
2577 "G_TYPE_INSTANCE_GET_PRIVATE(%s,%s,%sPrivate);\n",
2578 ((FuncArg *)m->args->data)->name,
2579 ((FuncArg *)m->args->data)->name,
2582 } else if(always_private_struct) {
2583 out_printf(out, "\t%s->_priv = NULL;\n",
2584 ((FuncArg *)m->args->data)->name);
2586 if(initializers > 0) {
2588 for(li = ((Class *)class)->nodes;
2592 Variable *v = (Variable *)n;
2593 if(n->type != VARIABLE_NODE ||
2594 v->scope == CLASS_SCOPE)
2596 print_initializer(m, v);
2599 if(glade_widgets > 0) {
2601 for(li = ((Class *)class)->nodes;
2605 Variable *v = (Variable *)n;
2606 if(n->type != VARIABLE_NODE ||
2607 v->scope == CLASS_SCOPE)
2609 print_glade_widget(m, v);
2612 } else if(m->method == CLASS_INIT_METHOD) {
2613 gboolean did_base_obj = FALSE;
2616 out_addline_infile(out, m->line_no);
2617 print_method(out, "static ", "\n", "", " ", "", "\n",
2618 m, FALSE, FALSE, FALSE, TRUE, TRUE,
2620 out_printf(out, "{\n");
2622 out_addline_outfile(out);
2624 "#define __GOB_FUNCTION__ \"%s::class_init\"\n",
2626 if (set_properties > 0 ||
2627 get_properties > 0 ||
2634 "g_object_class%s = "
2635 "(GObjectClass*) %s;\n",
2637 ((FuncArg *)m->args->data)->name);
2638 did_base_obj = TRUE;
2643 ((FuncArg *)m->args->data)->name,
2648 "\n\tg_type_class_add_private(%s,sizeof(%sPrivate));\n",
2649 ((FuncArg *)m->args->data)->name,
2652 if (initializers > 0) {
2654 for(li = ((Class *)class)->nodes;
2658 Variable *v = (Variable *)n;
2659 if(n->type == VARIABLE_NODE &&
2660 v->scope == CLASS_SCOPE)
2661 print_initializer(m, v);
2665 out_printf(out, "\n\tparent_class = ");
2667 out_printf(out, "(%sClass *)", ptypebase);
2668 out_printf(out, "g_type_class_ref (%s);\n",
2674 set_def_handlers(c, ((FuncArg *)m->args->data)->name);
2676 /* if there are no handlers for these things, we
2677 * need to set them up here */
2678 if(need_constructor)
2679 out_printf(out, "\tg_object_class->constructor "
2680 "= ___constructor;\n");
2681 if(need_dispose && !dispose_handler)
2682 out_printf(out, "\tg_object_class->dispose "
2684 if(need_finalize && !finalize_handler)
2685 out_printf(out, "\tg_object_class->finalize = "
2688 if(get_properties > 0 || set_properties > 0)
2691 if (c->bonobo_object_class != NULL) {
2692 make_bonobo_object_epv (c, ((FuncArg *)m->args->data)->name);
2698 out_printf(out, " {\n");
2699 out_addline_infile(out, m->ccode_line);
2700 out_printf(out, "%s\n", m->cbuf);
2701 out_addline_outfile(out);
2702 out_printf(out, " }\n");
2704 out_printf(out, "}\n"
2705 "#undef __GOB_FUNCTION__\n");
2710 add_argument (Argument *a, gboolean is_set)
2714 char *the_type_lower;
2719 line_no = a->set_line;
2722 line_no = a->get_line;
2726 s = g_strdup(a->name);
2728 out_printf(out, "\tcase PROP_%s:\n\t{", s);
2730 the_type_lower = g_strdup (a->gtktype);
2731 gob_strdown (the_type_lower);
2733 /* HACK because there is no g_value_set/get for unichar */
2734 if (strcmp (the_type_lower, "unichar") == 0) {
2735 g_free (the_type_lower);
2736 the_type_lower = g_strdup ("uint");
2741 const char *unused = "";
2743 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
2744 unused = " G_GNUC_UNUSED";
2747 if (a->atype != NULL &&
2748 /* gcc -Wbad-function-cast is wanking stupid, moronic
2749 and otherwise evil so we should just use a (gint)
2750 or (guint) cast, not the specific type cast */
2752 (strcmp (a->gtktype, "ENUM") != 0 &&
2753 strcmp (a->gtktype, "FLAGS") != 0)))
2754 cast = get_type (a->atype, TRUE);
2756 cast = g_strdup (get_cast (a->gtktype, FALSE));
2758 out_printf (out, "\t%s ARG%s = (%s) g_value_get_%s (VAL);\n",
2759 cast, unused, cast, the_type_lower);
2762 } else if ( ! is_set) {
2765 if (a->atype != NULL)
2766 cast = get_type (a->atype, TRUE);
2768 cast = g_strdup (get_cast (a->gtktype, FALSE));
2769 out_printf (out, "\t%s ARG;\n"
2770 "\tmemset (&ARG, 0, sizeof (%s));\n",
2776 out_printf(out, "\t\t{\n");
2778 out_addline_infile (out, line_no);
2779 out_printf (out, "%s\n", cbuf);
2781 out_addline_outfile (out);
2782 out_printf (out, "\t\t}\n");
2784 if (strcmp (a->gtktype, "OBJECT") == 0)
2785 out_printf (out, "\t\tg_value_set_%s (VAL, G_OBJECT (ARG));\n",
2788 out_printf (out, "\t\t"
2789 "g_value_set_%s (VAL, ARG);\n",
2792 g_free (the_type_lower);
2795 (no_gnu || for_cpp /* g++ has a cow with G_GNUC_UNUSED */)) {
2796 out_printf (out, "\t\tif (&ARG) break;\n");
2799 out_printf (out, "\t\tbreak;\n");
2801 out_printf (out, "\t}\n");
2805 add_property (Property *p, gboolean is_set)
2808 char *the_type_lower;
2814 line_no = p->set_line;
2817 line_no = p->get_line;
2822 name_upper = g_strdup (p->name);
2823 gob_strup (name_upper);
2824 the_type_lower = g_strdup (p->gtktype);
2825 gob_strdown (the_type_lower);
2827 out_printf (out, "\tcase PROP_%s:\n", name_upper);
2829 out_printf(out, "\t\t{\n");
2831 out_addline_infile (out, line_no);
2832 out_printf (out, "%s\n", cbuf);
2834 out_addline_outfile (out);
2835 out_printf (out, "\t\t}\n");
2837 g_free (name_upper);
2838 g_free (the_type_lower);
2840 out_printf (out, "\t\tbreak;\n");
2844 add_getset_arg(Class *c, gboolean is_set)
2847 const char *unused = "";
2848 const char *hack_unused = "";
2850 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
2851 unused = " G_GNUC_UNUSED";
2853 hack_unused = "if (&VAL || &pspec) break;\n\t\t";
2856 out_printf(out, "\nstatic void\n"
2857 "___object_%s_property (GObject *object,\n"
2858 "\tguint property_id,\n"
2859 "\t%sGValue *VAL%s,\n"
2860 "\tGParamSpec *pspec%s)\n"
2861 "#define __GOB_FUNCTION__ \"%s::%s_property\"\n"
2864 "\tself = %s (object);\n\n"
2865 "\tswitch (property_id) {\n",
2866 is_set ? "set" : "get",
2867 is_set ? "const " : "",
2871 is_set ? "set" : "get",
2876 for (li = c->nodes; li != NULL; li = li->next) {
2878 if (n->type == PROPERTY_NODE)
2879 add_property ((Property *)n, is_set);
2880 else if (n->type == ARGUMENT_NODE)
2881 add_argument ((Argument *)n, is_set);
2883 out_printf (out, "\tdefault:\n"
2884 "/* Apparently in g++ this is needed, glib is b0rk */\n"
2885 "#ifndef __PRETTY_FUNCTION__\n"
2886 "# undef G_STRLOC\n"
2887 "# define G_STRLOC __FILE__ \":\" G_STRINGIFY (__LINE__)\n"
2889 "\t\tG_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);\n"
2890 "\t\t%sbreak;\n\t}\n"
2892 "#undef __GOB_FUNCTION__\n", hack_unused);
2896 print_checks (Method *m, FuncArg *fa)
2900 gboolean checked_null = FALSE;
2901 is_void = (strcmp(m->mtype->name, "void")==0 &&
2902 m->mtype->pointer == NULL);
2904 for(li = fa->checks; li != NULL; li = li->next) {
2905 Check *ch = li->data;
2907 /* point to the method prot in .gob for failed checks */
2909 out_addline_infile(out, m->line_no);
2911 out_printf(out, "\tg_return_if_fail (");
2913 out_printf(out, "\tg_return_val_if_fail (");
2914 switch(ch->chtype) {
2916 out_printf(out, "%s != NULL", fa->name);
2917 checked_null = TRUE;
2920 s = make_pre_macro(fa->atype->name, "IS");
2922 out_printf(out, "%s (%s)", s, fa->name);
2924 /* if not check null, null may be valid */
2925 out_printf(out, "!(%s) || %s (%s)", fa->name,
2930 out_printf(out, "%s < %s", fa->name, ch->number);
2933 out_printf(out, "%s > %s", fa->name, ch->number);
2936 out_printf(out, "%s <= %s", fa->name, ch->number);
2939 out_printf(out, "%s >= %s", fa->name, ch->number);
2942 out_printf(out, "%s == %s", fa->name, ch->number);
2945 out_printf(out, "%s != %s", fa->name, ch->number);
2949 out_printf(out, ");\n");
2951 out_printf(out, ", (");
2952 print_type(out, m->mtype, TRUE);
2953 out_printf(out, ")%s);\n",
2954 m->onerror?m->onerror:"0");
2960 print_preconditions(Method *m)
2964 for(li=m->args;li;li=g_list_next(li)) {
2965 FuncArg *fa = li->data;
2967 print_checks(m, fa);
2970 out_addline_outfile(out);
2974 print_method_body (Method *m, gboolean pre, gboolean unused_self)
2976 out_printf(out, "{\n");
2978 out_addline_outfile(out);
2979 out_printf(out, "#define __GOB_FUNCTION__ \"%s::%s\"\n",
2980 ((Class *)class)->otype,
2983 print_preconditions(m);
2987 (no_gnu || for_cpp) &&
2989 ((FuncArg *)(m->args->data))->name != NULL &&
2990 strcmp (((FuncArg *)(m->args->data))->name, "self") == 0) {
2991 out_printf (out, "\tif (&self) { ; }\n");
2994 /* Note: the trailing }'s are on one line, this is so
2995 that we get the no return warning correctly and point to
2996 the correct line in the .gob file, yes this is slightly
2997 ugly in the .c file, but that is not supposed to be
2998 human readable anyway. */
3000 out_printf(out, "{\n");
3002 out_addline_infile(out, m->ccode_line);
3003 out_printf(out, "\t%s}", m->cbuf);
3006 /* Note, there is no \n between the last } and this } so that
3007 * errors/warnings reported on the end of the body get pointed to the
3008 * right line in the .gob source */
3009 out_printf(out, "}\n");
3012 out_addline_outfile(out);
3013 out_printf(out, "#undef __GOB_FUNCTION__\n");
3017 put_signal_args (Method *m)
3023 if (m->args->next == NULL)
3026 for (ali = m->gtktypes->next, li = m->args->next, i = 1;
3027 li != NULL && ali != NULL;
3028 li = li->next, ali = ali->next, i++) {
3029 FuncArg *fa = li->data;
3030 char *str = ali->data;
3031 char *cast = g_strdup (get_cast (str, FALSE));
3032 /* FIXME: This code is so fucking ugly it hurts */
3033 gboolean do_static =
3034 (strcmp (str, "STRING") == 0 ||
3035 strcmp (str, "BOXED") == 0 ||
3036 strncmp (str, "BOXED_", 6) == 0);
3041 cast = get_type (fa->atype, TRUE);
3043 /* we should have already proved before that
3044 the we know all the types */
3045 g_assert (cast != NULL);
3047 if (strncmp (str, "BOXED_", 6) == 0)
3048 t = g_strdup (&(str[6]));
3050 t = g_strconcat ("G_TYPE_", str, NULL);
3053 "\t___param_values[%d].g_type = 0;\n"
3054 "\tg_value_init (&___param_values[%d], %s);\n",
3058 if (strcmp (str, "UNICHAR") == 0)
3059 /* hack because glib is braindamaged */
3060 set_func = g_strdup ("g_value_set_uint");
3061 else if (strncmp (str, "BOXED_", 6) == 0)
3062 set_func = g_strdup ("g_value_set_static_boxed");
3064 set_func = g_strdup_printf ("g_value_set%s_%s",
3065 do_static ? "_static" : "",
3067 gob_strdown (set_func);
3069 out_printf (out, "\t%s (&___param_values[%d], (%s) %s);\n\n",
3070 set_func, i, cast, fa->name);
3078 clear_signal_args (Method *m)
3083 out_printf (out, "\n\tg_value_unset (&___param_values[0]);\n");
3085 if (m->args->next == NULL)
3088 for (li = m->args->next, i = 1;
3090 li = li->next, i++) {
3092 "\tg_value_unset (&___param_values[%d]);\n", i);
3097 get_arg_names_for_macro (Method *m)
3101 GString *gs = g_string_new(NULL);
3103 for(li=m->args;li;li=g_list_next(li)) {
3104 FuncArg *arg = li->data;
3105 g_string_sprintfa (gs, "%s___%s", sep, arg->name);
3108 return g_string_free (gs, FALSE);
3111 static gboolean method_is_void(Method *m)
3113 return !strcmp(m->mtype->name, "void") && !m->mtype->pointer;
3116 static const char *method_err_retval(Method *m)
3118 if (method_is_void(m))
3126 put_interface_parent_handler(Method *m)
3128 const char *errval = method_err_retval(m);
3129 char *name = replace_sep(m->interface, '_');
3130 char *args = get_arg_names_for_macro(m);
3132 out_printf(out, "#define PARENT_HANDLER(%s) (%s_parent_iface \\\n"
3133 "\t? %s_parent_iface->%s(%s) \\\n"
3134 "\t: %s)\n", args, name, name, m->id, args, errval);
3141 put_method(Method *m)
3143 char *s, *args, *doc;
3145 is_void = (strcmp(m->mtype->name, "void")==0 &&
3146 m->mtype->pointer == NULL);
3147 out_printf(out, "\n");
3148 if(m->method != OVERRIDE_METHOD) {
3149 doc = get_gtk_doc(m->id);
3151 out_printf(out, "%s", doc);
3157 case REGULAR_METHOD:
3159 out_addline_infile(out, m->line_no);
3160 if(m->scope == PRIVATE_SCOPE)
3161 print_method(out, "static ", "\n", "", " ", "", "\n",
3162 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3163 else /* PUBLIC, PROTECTED */
3164 print_method(out, "", "\n", "", " ", "", "\n",
3165 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3168 out_addline_outfile(out);
3169 put_interface_parent_handler(m);
3172 print_method_body(m, TRUE, TRUE);
3175 out_printf(out, "#undef PARENT_HANDLER\n");
3178 /* the outfile line was added above */
3180 case SIGNAL_FIRST_METHOD:
3181 case SIGNAL_LAST_METHOD:
3183 out_addline_infile(out, m->line_no);
3184 if(m->scope == PRIVATE_SCOPE)
3185 print_method(out, "static ", "\n", "", " ", "", "\n",
3186 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3187 else /* PUBLIC, PROTECTED */
3188 print_method(out, "", "\n", "", " ", "", "\n",
3189 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3190 out_printf (out, "{\n");
3192 out_addline_outfile (out);
3195 "\tGValue ___param_values[%d];\n"
3196 "\tGValue ___return_val;\n\n"
3197 "memset (&___return_val, 0, "
3198 "sizeof (___return_val));\n"
3199 "memset (&___param_values, 0, "
3200 "sizeof (___param_values));\n\n",
3201 g_list_length (m->args));
3203 print_preconditions (m);
3206 "\n\t___param_values[0].g_type = 0;\n"
3207 "\tg_value_init (&___param_values[0], G_TYPE_FROM_INSTANCE (%s));\n"
3208 "\tg_value_set_instance (&___param_values[0], (gpointer) %s);\n\n",
3209 ((FuncArg *)m->args->data)->name,
3210 ((FuncArg *)m->args->data)->name);
3212 put_signal_args (m);
3214 if (strcmp (m->gtktypes->data, "NONE") != 0) {
3215 const char *defret = NULL;
3217 out_printf (out, "\tg_value_init (&___return_val, G_TYPE_%s);\n",
3218 (char *)m->gtktypes->data);
3220 if (m->defreturn != NULL)
3221 defret = m->defreturn;
3222 else if (m->onerror != NULL)
3223 defret = m->onerror;
3225 if (defret != NULL) {
3227 /* FIXME: This code is so fucking ugly it hurts */
3228 gboolean do_static =
3229 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
3230 strcmp ((char *)m->gtktypes->data, "BOXED") == 0);
3231 char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
3233 cast = get_type (m->mtype, TRUE);
3235 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
3236 /* hack because glib is braindamaged */
3237 set_func = g_strdup ("g_value_set_uint");
3239 set_func = g_strdup_printf ("g_value_set%s_%s",
3240 do_static ? "_static" : "",
3241 (char *)m->gtktypes->data);
3242 gob_strdown (set_func);
3244 out_printf (out, "\t%s (&___return_val, (%s) (%s));\n",
3245 set_func, cast, defret);
3250 out_printf (out, "\n");
3253 s = g_strdup (m->id);
3256 out_printf(out, "\tg_signal_emitv (___param_values,\n"
3257 "\t\tobject_signals[%s_SIGNAL],\n"
3258 "\t\t0 /* detail */,\n"
3259 "\t\t&___return_val);\n", s);
3263 clear_signal_args (m);
3265 if (strcmp (m->gtktypes->data, "NONE") != 0) {
3266 char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
3268 /* Hack because glib is very very braindead */
3270 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
3271 strcmp ((char *)m->gtktypes->data, "BOXED") == 0 ||
3272 strcmp ((char *)m->gtktypes->data, "OBJECT") == 0 ||
3273 strcmp ((char *)m->gtktypes->data, "PARAM") == 0);
3275 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
3276 /* hack because glib is braindamaged */
3277 getfunc = g_strdup ("g_value_get_uint");
3279 getfunc = g_strdup_printf ("g_value_%s_%s",
3280 do_dup ? "dup" : "get",
3281 (char *)m->gtktypes->data);
3282 gob_strdown (getfunc);
3285 cast = get_type (m->mtype, TRUE);
3290 print_type (out, m->mtype, TRUE);
3292 " ___ret = (%s) %s (&___return_val);\n"
3293 "\t\tg_value_unset (&___return_val);\n"
3294 "\t\treturn ___ret;\n"
3301 out_printf(out, "}\n");
3306 out_addline_infile(out, m->line_no);
3307 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
3308 m, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE);
3309 print_method_body(m, FALSE, TRUE);
3310 /* the outfile line was added above */
3312 case VIRTUAL_METHOD:
3314 out_addline_infile(out, m->line_no);
3315 if(m->scope==PRIVATE_SCOPE)
3316 print_method(out, "static ", "\n", "", " ", "", "\n",
3317 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3318 else /* PUBLIC, PROTECTED */
3319 print_method(out, "", "\n", "", " ", "", "\n",
3320 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3321 out_printf(out, "{\n");
3322 out_addline_outfile(out);
3323 out_printf(out, "\t%sClass *klass;\n", typebase);
3324 print_preconditions(m);
3325 out_printf(out, "\tklass = %s_GET_CLASS(%s);\n\n"
3326 "\tif(klass->%s)\n",
3327 macrobase, ((FuncArg *)m->args->data)->name,
3329 if(strcmp(m->mtype->name, "void") == 0 &&
3330 m->mtype->pointer == NULL) {
3332 out_printf(out, "\t\t(*klass->%s)(%s",
3334 ((FuncArg *)m->args->data)->name);
3335 for(li=m->args->next;li;li=g_list_next(li)) {
3336 FuncArg *fa = li->data;
3337 out_printf(out, ",%s", fa->name);
3339 out_printf(out, ");\n}\n");
3342 out_printf(out, "\t\treturn (*klass->%s)(%s",
3344 ((FuncArg *)m->args->data)->name);
3345 for(li=m->args->next;li;li=g_list_next(li)) {
3346 FuncArg *fa = li->data;
3347 out_printf(out, ",%s", fa->name);
3349 out_printf(out, ");\n"
3352 print_type(out, m->mtype, TRUE);
3354 out_printf(out, ")(%s);\n}\n", m->defreturn);
3356 out_printf(out, ")(%s);\n}\n", m->onerror);
3358 out_printf(out, ")(0);\n}\n");
3364 out_addline_infile(out, m->line_no);
3365 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
3366 m, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE);
3367 print_method_body(m, FALSE, TRUE);
3368 /* the outfile line was added above */
3370 case OVERRIDE_METHOD:
3374 out_addline_infile(out, m->line_no);
3375 s = g_strdup_printf("\n___%x_", (guint)m->unique_id);
3376 print_method(out, "static ", s, "", " ", "", "\n",
3377 m, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE);
3379 out_addline_outfile(out);
3380 s = replace_sep(m->otype, '_');
3382 args = get_arg_names_for_macro(m);
3384 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
3385 "\t{ if(%s_CLASS(parent_class)->%s) \\\n"
3386 "\t\t(* %s_CLASS(parent_class)->%s)(%s); }\n",
3387 args, s, m->id, s, m->id, args);
3389 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
3390 "\t((%s_CLASS(parent_class)->%s)? \\\n"
3391 "\t\t(* %s_CLASS(parent_class)->%s)(%s): \\\n"
3393 args, s, m->id, s, m->id, args);
3394 out_printf(out, "(");
3395 print_type(out, m->mtype, TRUE);
3396 out_printf(out, ")%s))\n",
3397 m->onerror?m->onerror:"0");
3401 print_method_body(m, TRUE, TRUE);
3402 /* the outfile line was added above */
3403 out_printf(out, "#undef PARENT_HANDLER\n");
3405 case CONSTRUCTOR_METHOD:
3406 case DISPOSE_METHOD:
3407 case FINALIZE_METHOD:
3409 out_addline_infile(out, m->line_no);
3410 print_method(out, "static ", "\n", "", " ", "", "\n",
3411 m, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE);
3412 print_method_body(m, TRUE, TRUE);
3413 /* the outfile line was added above */
3422 char *outfile, *outfileh, *outfileph;
3424 outfilebase = g_strconcat (fullfilebase, for_cpp ? ".cc" : ".c", NULL);
3425 outfile = g_strconcat(outfilebase, no_touch ? "#gob#" : "", NULL);
3427 outfilehbase = g_strconcat (fullfilebase, ".h", NULL);
3428 outfileh = g_strconcat(outfilehbase, no_touch_headers ? "#gob#" : "", NULL);
3430 if ((privates > 0 || protecteds > 0 ||
3431 private_header == PRIVATE_HEADER_ALWAYS) &&
3432 private_header != PRIVATE_HEADER_NEVER) {
3433 char sep[2] = {0,0};
3436 outfilephbase = g_strconcat (fullfilebase, sep, "private.h", NULL);
3437 outfileph = g_strconcat (outfilephbase, no_touch ? "#gob#" : "", NULL);
3439 outfilephbase = NULL;
3445 out = fopen (outfile, "w");
3447 error_printf (GOB_ERROR, 0,
3448 "Cannot open outfile: %s", outfile);
3450 outh = fopen (outfileh, "w");
3452 error_printf (GOB_ERROR, 0,
3453 "Cannot open outfile: %s", outfileh);
3455 if (outfileph != NULL) {
3456 outph = fopen (outfileph, "w");
3457 if (outph == NULL) {
3458 error_printf (GOB_ERROR, 0,
3459 "Cannot open outfile: %s",
3467 put_argument_nongnu_wrappers (Class *c)
3471 if (get_properties < 0 && set_properties < 0)
3474 for (li = c->nodes; li != NULL; li = li->next) {
3476 const char *name, *gtktype;
3482 if (n->type == ARGUMENT_NODE) {
3483 Argument *a = (Argument *)n;
3485 gtktype = a->gtktype;
3487 get = a->get != NULL;
3488 set = a->set != NULL;
3489 } else if (n->type == PROPERTY_NODE) {
3490 Property *p = (Property *)n;
3492 gtktype = p->gtktype;
3494 get = p->get != NULL;
3495 set = p->set != NULL;
3500 aname = g_strdup (name);
3504 cast = get_type (atype, TRUE);
3506 cast = g_strdup (get_cast (gtktype, TRUE));
3510 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3511 "\"%s\",(%s)(arg)\n",
3512 macrobase, aname, name, cast);
3514 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3515 "\"%s\",(%s*)(arg)\n",
3516 macrobase, aname, name, cast);
3519 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3521 macrobase, aname, name);
3523 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3525 macrobase, aname, name);
3533 put_argument_gnu_wrappers(Class *c)
3537 if(get_properties < 0 && set_properties < 0)
3540 for (li = c->nodes; li != NULL; li = li->next) {
3542 const char *name, *gtktype;
3548 if (n->type == ARGUMENT_NODE) {
3549 Argument *a = (Argument *)n;
3551 gtktype = a->gtktype;
3553 get = a->get != NULL;
3554 set = a->set != NULL;
3555 } else if (n->type == PROPERTY_NODE) {
3556 Property *p = (Property *)n;
3558 gtktype = p->gtktype;
3560 get = p->get != NULL;
3561 set = p->set != NULL;
3566 aname = g_strdup (name);
3570 cast = get_type (atype, TRUE);
3572 cast = g_strdup (get_cast (gtktype, TRUE));
3576 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3577 "\"%s\", __extension__ ({%sz = (arg); z;})\n",
3578 macrobase, aname, name, cast);
3580 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3581 "\"%s\", __extension__ ({%s*z = (arg); z;})\n",
3582 macrobase, aname, name, cast);
3585 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3587 macrobase, aname, name);
3589 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3591 macrobase, aname, name);
3599 print_ccode_block(CCode *cc)
3602 switch(cc->cctype) {
3604 /* HT code is printed exactly like normal header
3605 code but is printed before */
3608 out_printf(fp, "\n");
3611 /* AT code is printed exactly like normal 'all'
3612 code but is printed before */
3615 out_printf(outph, "\n");
3616 out_printf(outph, "%s\n", cc->cbuf);
3617 out_addline_infile(outph, cc->line_no);
3618 out_addline_outfile(outph);
3620 out_printf(outh, "\n");
3621 out_printf(outh, "%s\n", cc->cbuf);
3623 out_printf(fp, "\n");
3624 out_addline_infile(fp, cc->line_no);
3630 out_printf(fp, "\n");
3631 out_addline_infile(fp, cc->line_no);
3638 out_printf(fp, "\n");
3639 out_addline_infile(fp, cc->line_no);
3642 out_printf(fp, "%s\n", cc->cbuf);
3643 if(cc->cctype == C_CCODE ||
3644 cc->cctype == AD_CCODE ||
3645 cc->cctype == A_CCODE ||
3646 cc->cctype == AT_CCODE ||
3647 cc->cctype == PH_CCODE)
3648 out_addline_outfile(fp);
3652 print_class_block(Class *c)
3656 gboolean printed_private = FALSE;
3660 out_printf(outph ? outph : outh, "#include <gtk/gtk.h>\n");
3661 out_printf(outph ? outph : outh, "#include <glade/glade-xml.h>\n\n");
3665 out_printf(out, "/* utility types we may need */\n");
3666 if(special_array[SPECIAL_2POINTER])
3667 out_printf(out, "typedef struct { "
3668 "gpointer a; gpointer b; "
3669 "} ___twopointertype;\n");
3670 if(special_array[SPECIAL_3POINTER])
3671 out_printf(out, "typedef struct { "
3672 "gpointer a; gpointer b; "
3674 "} ___threepointertype;\n");
3675 if(special_array[SPECIAL_INT_POINTER])
3676 out_printf(out, "typedef struct { "
3677 "gint a; gpointer b; "
3678 "} ___intpointertype;\n");
3679 out_printf(out, "\n");
3682 out_printf(outh, "\n/*\n"
3683 " * Type checking and casting macros\n"
3685 out_printf(outh, "#define %s\t"
3686 "(%s_get_type())\n",
3687 macrotype, funcbase);
3688 out_printf(outh, "#define %s(obj)\t"
3689 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s)\n",
3690 macrobase, funcbase, typebase);
3691 out_printf(outh, "#define %s_CONST(obj)\t"
3692 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s const)\n",
3693 macrobase, funcbase, typebase);
3694 out_printf(outh, "#define %s_CLASS(klass)\t"
3695 "G_TYPE_CHECK_CLASS_CAST((klass), %s_get_type(), %sClass)\n",
3696 macrobase, funcbase, typebase);
3697 out_printf(outh, "#define %s(obj)\t"
3698 "G_TYPE_CHECK_INSTANCE_TYPE((obj), %s_get_type ())\n\n",
3701 "#define %s_GET_CLASS(obj)\t"
3702 "G_TYPE_INSTANCE_GET_CLASS((obj), %s_get_type(), %sClass)\n",
3703 macrobase, funcbase, typebase);
3705 if ( ! no_self_alias) {
3706 out_printf(out, "/* self casting macros */\n");
3707 out_printf(out, "#define SELF(x) %s(x)\n", macrobase);
3708 out_printf(out, "#define SELF_CONST(x) %s_CONST(x)\n", macrobase);
3709 out_printf(out, "#define IS_SELF(x) %s(x)\n", macrois);
3710 out_printf(out, "#define TYPE_SELF %s\n", macrotype);
3711 out_printf(out, "#define SELF_CLASS(x) %s_CLASS(x)\n\n",
3713 out_printf(out, "#define SELF_GET_CLASS(x) %s_GET_CLASS(x)\n\n",
3716 out_printf(out, "/* self typedefs */\n");
3717 out_printf(out, "typedef %s Self;\n", typebase);
3718 out_printf(out, "typedef %sClass SelfClass;\n\n", typebase);
3722 always_private_struct) {
3723 out_printf (outh, "\n/* Private structure type */\n");
3724 out_printf (outh, "typedef struct _%sPrivate %sPrivate;\n",
3725 typebase, typebase);
3727 out_printf (outh, "/* There are no privates, this "
3728 "structure is thus never defined */\n");
3731 out_printf (outh, "\n/*\n"
3732 " * Main object structure\n"
3734 s = replace_sep (c->otype, '_');
3736 out_printf (outh, "#ifndef __TYPEDEF_%s__\n"
3737 "#define __TYPEDEF_%s__\n", s, s);
3739 out_printf (outh, "typedef struct _%s %s;\n"
3740 "#endif\n", typebase, typebase);
3741 out_printf (outh, "struct _%s {\n\t%s __parent__;\n",
3742 typebase, ptypebase);
3743 for (li = c->nodes; li; li=li->next) {
3744 static gboolean printed_public = FALSE;
3746 Variable *v = (Variable *)n;
3747 if(n->type == VARIABLE_NODE &&
3748 v->scope == PUBLIC_SCOPE) {
3749 if( ! printed_public) {
3750 out_printf(outh, "\t/*< public >*/\n");
3751 printed_public = TRUE;
3753 put_variable((Variable *)n, outh);
3756 /* put protecteds always AFTER publics */
3757 for (li = c->nodes; li != NULL; li = li->next) {
3759 Variable *v = (Variable *)n;
3760 if (n->type == VARIABLE_NODE &&
3761 v->scope == PROTECTED_SCOPE) {
3762 if ( ! printed_private) {
3763 out_printf (outh, "\t/*< private >*/\n");
3764 printed_private = TRUE;
3766 put_variable ((Variable *)n, outh);
3770 always_private_struct) {
3771 if ( ! printed_private)
3772 out_printf (outh, "\t/*< private >*/\n");
3773 out_printf (outh, "\t%sPrivate *_priv;\n", typebase);
3775 out_printf (outh, "};\n");
3780 /* if we are to stick this into the private
3781 header, if not stick it directly into the
3788 out_printf (outfp, "struct _%sPrivate {\n",
3792 for(li=c->nodes; li; li=li->next) {
3794 Variable *v = (Variable *)n;
3795 if(n->type == VARIABLE_NODE &&
3796 v->scope == PRIVATE_SCOPE) {
3797 out_addline_infile(outfp, v->line_no);
3798 put_variable(v, outfp);
3801 out_addline_outfile(outfp);
3803 out_printf(outfp, "};\n");
3806 out_printf(outh, "\n/*\n"
3807 " * Class definition\n"
3809 out_printf(outh, "typedef struct _%sClass %sClass;\n",
3810 typebase, typebase);
3812 "struct _%sClass {\n\t%sClass __parent__;\n",
3813 typebase, ptypebase);
3814 for(li = c->nodes; li != NULL; li = li->next) {
3816 if(n->type == METHOD_NODE)
3817 put_vs_method((Method *)n);
3819 /* If BonoboX type class put down the epv */
3820 if (c->bonobo_object_class != NULL) {
3822 "\t/* Bonobo object epv */\n"
3823 "\tPOA_%s__epv _epv;\n",
3824 c->bonobo_object_class);
3826 /* put class scope variables */
3827 for (li = c->nodes; li != NULL; li = li->next) {
3829 Variable *v = (Variable *)n;
3830 if (n->type == VARIABLE_NODE &&
3831 v->scope == CLASS_SCOPE)
3832 put_variable ((Variable *)n, outh);
3834 out_printf (outh, "};\n\n");
3836 out_printf (out, "/* here are local prototypes */\n");
3837 if (set_properties > 0) {
3838 out_printf (out, "static void ___object_set_property "
3839 "(GObject *object, guint property_id, "
3840 "const GValue *value, GParamSpec *pspec);\n");
3842 if (get_properties > 0) {
3843 out_printf (out, "static void ___object_get_property "
3844 "(GObject *object, guint property_id, "
3845 "GValue *value, GParamSpec *pspec);\n");
3848 out_printf (outh, "\n/*\n"
3849 " * Public methods\n"
3852 if (!overrode_get_type) {
3854 * For ordinary "static" types it should be safe to mark the
3855 * get_type implementation as const, since the get_type
3856 * function return really is constant at the call boundary
3857 * (even though there is an initial setup on the first call).
3858 * But for dynamic types, since the registration is explicitly
3859 * separated, we need to settle for "pure" as the results of
3860 * get_type differ before and after type registration.
3862 out_printf(outh, "GType\t%s_get_type\t(void) %s;\n", funcbase,
3863 c->dynamic ? "G_GNUC_PURE" : "G_GNUC_CONST");
3867 out_printf(outh, "void\t%s_register_type\t(GTypeModule *);\n",
3871 for(li = c->nodes; li != NULL; li = li->next) {
3873 if(n->type == METHOD_NODE) {
3874 put_pub_method((Method *)n);
3875 put_prot_method((Method *)n);
3876 put_priv_method_prot((Method *)n);
3880 /* this idea is less and less apealing to me */
3882 out_printf (outh, "\n/*\n"
3883 " * Signal connection wrapper macros\n"
3886 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3887 put_signal_macros (c, TRUE);
3888 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3889 put_signal_macros (c, FALSE);
3890 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n");
3892 put_signal_macros (c, FALSE);
3893 out_printf(outh, "\n");
3896 out_printf (out, "\n/*\n"
3897 " * Signal connection wrapper macro shortcuts\n"
3899 put_local_signal_macros (c);
3900 out_printf(outh, "\n");
3903 /* argument wrapping macros */
3904 if(get_properties > 0 || set_properties > 0) {
3905 out_printf(outh, "\n/*\n"
3906 " * Argument wrapping macros\n"
3909 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3910 put_argument_gnu_wrappers(c);
3911 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3912 put_argument_nongnu_wrappers(c);
3913 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n");
3915 put_argument_nongnu_wrappers(c);
3920 for(li = c->nodes; li != NULL; li = li->next) {
3922 if(n->type == METHOD_NODE)
3923 add_signal_prots((Method *)n);
3929 if(any_method_to_alias(c)) {
3930 out_printf (out, "/* Short form macros */\n");
3931 make_method_aliases (c);
3934 add_interface_inits (c);
3936 if (!overrode_get_type) {
3937 if (c->bonobo_object_class != NULL)
3938 add_bonobo_object_get_type();
3939 else if (c->dynamic)
3940 add_dynamic_get_type();
3945 out_printf (out, "/* a macro for creating a new object of our type */\n");
3947 "#define GET_NEW ((%s *)g_object_new(%s_get_type(), NULL))\n\n",
3948 typebase, funcbase);
3950 out_printf (out, "/* a function for creating a new object of our type */\n");
3951 out_printf (out, "#include <stdarg.h>\n");
3953 "static %s * GET_NEW_VARG (const char *first, ...)%s;\n"
3954 "static %s *\nGET_NEW_VARG (const char *first, ...)\n"
3955 "{\n\t%s *ret;\n\tva_list ap;\n"
3956 "\tva_start (ap, first);\n"
3957 "\tret = (%s *)g_object_new_valist (%s_get_type (), "
3960 "\treturn ret;\n}\n\n",
3962 no_gnu ? "" : " G_GNUC_UNUSED",
3963 typebase, typebase, typebase, funcbase);
3967 out_printf (out, "/* a function to connect glade callback */\n");
3968 out_printf (out,"static void\n"
3969 "___glade_xml_connect_foreach(const gchar *handler_name,\n"
3970 "GObject *object,\n"
3971 "const gchar *signal_name,\n"
3972 "const gchar *signal_data,\n"
3973 "GObject *connect_object,\n"
3975 "gpointer user_data)\n"
3977 "\tstatic GModule * allsymbols = NULL;\n"
3979 "\tif (!allsymbols) allsymbols = g_module_open(NULL, 0);\n"
3980 "\tif (allsymbols) {\n"
3981 "\t\tgchar * func_name = g_strdup_printf(\"%s_%%s\", handler_name);\n"
3982 "\t\tGCallback func;\n"
3984 "\t\tif (!g_module_symbol(allsymbols, func_name, (gpointer)&func)){\n"
3985 "\t\t\tif (!g_module_symbol(allsymbols, handler_name, (gpointer)&func)) {\n"
3986 "\t\t\t\tg_warning(\"could not find signal handler '%%s'.\", func_name);\n"
3987 "\t\t\t\tg_free(func_name);\n"
3992 "\t\t\tg_signal_connect_data(object, signal_name, func, user_data, NULL, G_CONNECT_AFTER | G_CONNECT_SWAPPED);\n"
3994 "\t\t\tg_signal_connect_data(object, signal_name, func, user_data, NULL, G_CONNECT_SWAPPED);\n"
3995 "\t\tg_free(func_name);\n"
4002 for (li = nodes; li != NULL; li = li->next) {
4003 Node *node = li->data;
4004 if (node->type == CCODE_NODE) {
4005 CCode *cc = (CCode *)node;
4006 if (cc->cctype == AD_CCODE)
4007 print_ccode_block (cc);
4011 if (need_constructor)
4012 add_constructor (c);
4022 if(set_properties > 0) {
4023 add_getset_arg(c, TRUE);
4026 if(get_properties > 0) {
4027 add_getset_arg(c, FALSE);
4030 for(li = c->nodes; li != NULL; li = li->next) {
4032 if(n->type == METHOD_NODE)
4033 put_method((Method *)n);
4036 add_bad_hack_to_avoid_unused_warnings(c);
4040 print_useful_macros(void)
4042 int major = 0, minor = 0, pl = 0;
4045 sscanf (VERSION, "%d.%d.%d", &major, &minor, &pl);
4046 out_printf (out, "#define GOB_VERSION_MAJOR %d\n", major);
4047 out_printf (out, "#define GOB_VERSION_MINOR %d\n", minor);
4048 out_printf (out, "#define GOB_VERSION_PATCHLEVEL %d\n\n", pl);
4050 /* Useful priv macro thingie */
4051 /* FIXME: this should be done the same way that priv is, as a var,
4053 out_printf (out, "#define selfp (self->_priv)\n\n");
4057 print_more_useful_macros (void)
4060 out_printf (out, "#define ___GOB_LIKELY(expr) (expr)\n");
4061 out_printf (out, "#define ___GOB_UNLIKELY(expr) (expr)\n");
4063 out_printf (out, "#ifdef G_LIKELY\n");
4064 out_printf (out, "#define ___GOB_LIKELY(expr) G_LIKELY(expr)\n");
4065 out_printf (out, "#define ___GOB_UNLIKELY(expr) G_UNLIKELY(expr)\n");
4066 out_printf (out, "#else /* ! G_LIKELY */\n");
4067 out_printf (out, "#define ___GOB_LIKELY(expr) (expr)\n");
4068 out_printf (out, "#define ___GOB_UNLIKELY(expr) (expr)\n");
4069 out_printf (out, "#endif /* G_LIKELY */\n");
4074 print_file_comments(void)
4076 out_printf(outh, "/* Generated by GOB (v%s)"
4077 " (do not edit directly) */\n\n", VERSION);
4079 out_printf(outph, "/* Generated by GOB (v%s)"
4080 " (do not edit directly) */\n\n", VERSION);
4081 out_printf(out, "/* Generated by GOB (v%s)"
4082 " (do not edit directly) */\n\n", VERSION);
4084 out_printf(out, "/* End world hunger, donate to the World Food Programme, http://www.wfp.org */\n\n");
4088 print_includes(void)
4090 gboolean found_header;
4093 /* We may need string.h for memset */
4094 if ( ! g_list_find_custom(include_files, "string.h", (GCompareFunc)strcmp)) {
4095 out_printf(out, "#include <string.h> /* memset() */\n\n");
4098 p = g_strconcat(filebase, ".h", NULL);
4099 found_header = TRUE;
4100 if( ! g_list_find_custom(include_files, p, (GCompareFunc)strcmp)) {
4101 out_printf(out, "#include \"%s.h\"\n\n", filebase);
4102 found_header = FALSE;
4106 /* if we are creating a private header see if it was included */
4108 char sep[2] = {0,0};
4111 p = g_strconcat(filebase, sep, "private.h", NULL);
4112 if( ! g_list_find_custom(include_files, p,
4113 (GCompareFunc)strcmp)) {
4114 out_printf(out, "#include \"%s%sprivate.h\"\n\n",
4118 error_printf(GOB_WARN, 0,
4119 "Implicit private header include "
4121 "\tsource file, while public "
4122 "header is at a custom location, "
4124 "\texplicitly include "
4125 "the private header below the "
4133 print_header_prefixes(void)
4137 p = replace_sep(((Class *)class)->otype, '_');
4139 out_printf(outh, "#ifndef __%s_H__\n#define __%s_H__\n\n", p, p);
4141 out_printf(outph, "#ifndef __%s_PRIVATE_H__\n"
4142 "#define __%s_PRIVATE_H__\n\n"
4143 "#include \"%s.h\"\n\n", p, p, filebase);
4146 if( ! no_extern_c) {
4147 out_printf(outh, "#ifdef __cplusplus\n"
4149 "#endif /* __cplusplus */\n\n");
4151 out_printf(outph, "#ifdef __cplusplus\n"
4153 "#endif /* __cplusplus */\n\n");
4158 print_header_postfixes(void)
4161 out_printf(outh, "\n#ifdef __cplusplus\n"
4163 "#endif /* __cplusplus */\n");
4164 out_printf(outh, "\n#endif\n");
4167 out_printf(outph, "\n#ifdef __cplusplus\n"
4169 "#endif /* __cplusplus */\n");
4170 out_printf(outph, "\n#endif\n");
4179 /* print the AT_CCODE and CT_CCODE blocks */
4180 for(li = nodes; li != NULL; li = li->next) {
4181 Node *node = li->data;
4182 if(node->type == CCODE_NODE) {
4183 CCode *cc = (CCode *)node;
4184 if (cc->cctype == AT_CCODE ||
4185 cc->cctype == CT_CCODE)
4186 print_ccode_block((CCode *)node);
4192 print_header_top(void)
4196 /* mandatory includes */
4197 out_printf (outh, "#include <glib.h>\n");
4198 out_printf (outh, "#include <glib-object.h>\n");
4200 /* print the HT_CCODE blocks */
4201 for (li = nodes; li != NULL; li = li->next) {
4202 Node *node = li->data;
4203 if (node->type == CCODE_NODE) {
4204 CCode *cc = (CCode *)node;
4205 if (cc->cctype == HT_CCODE)
4206 print_ccode_block ((CCode *)node);
4212 print_enum (EnumDef *enode)
4219 funcprefix = replace_sep (enode->etype, '_');
4220 gob_strdown (funcprefix);
4221 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
4223 type = remove_sep (enode->etype);
4225 out_printf (outh, "\ntypedef enum {\n");
4227 for (li = enode->values; li != NULL; li = li->next) {
4228 EnumValue *value = li->data;
4230 char *sname = gob_strdown (g_strdup (value->name));
4232 while ((p = strchr (sname, '_')) != NULL)
4235 out_printf (outh, "\t%s_%s", enode->prefix, value->name);
4236 if (value->value != NULL)
4237 out_printf (outh, " = %s", value->value);
4238 if (li->next != NULL)
4239 out_printf (outh, ",\n");
4241 out_printf (outh, "\n");
4243 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
4244 enode->prefix, value->name,
4245 enode->prefix, value->name,
4251 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
4253 out_printf (outh, "} %s;\n", type);
4255 str = make_pre_macro (enode->etype, "TYPE");
4256 out_printf (outh, "#define %s ", str);
4259 out_printf (outh, "%s_get_type()\n", funcprefix);
4260 out_printf (outh, "GType %s_get_type (void) G_GNUC_CONST;\n\n", funcprefix);
4263 "GType\n%s_get_type (void)\n"
4265 "\tstatic GType type = 0;\n"
4266 "\tif ___GOB_UNLIKELY(type == 0)\n"
4267 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
4270 funcprefix, type, funcprefix);
4272 g_free (funcprefix);
4277 print_flags (Flags *fnode)
4285 funcprefix = replace_sep (fnode->ftype, '_');
4286 gob_strdown (funcprefix);
4287 out_printf (out, "static const GFlagsValue _%s_values[] = {\n",
4289 type = remove_sep (fnode->ftype);
4291 out_printf (outh, "\ntypedef enum {\n");
4293 for (i = 0, li = fnode->values; li != NULL; i++, li = li->next) {
4294 const char *name = li->data;
4296 char *sname = gob_strdown (g_strdup (name));
4298 while ((p = strchr (sname, '_')) != NULL)
4301 out_printf (outh, "\t%s_%s = 1<<%d",
4302 fnode->prefix, name, i);
4303 if (li->next != NULL)
4304 out_printf (outh, ",\n");
4306 out_printf (outh, "\n");
4308 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
4309 fnode->prefix, name,
4310 fnode->prefix, name,
4316 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
4318 out_printf (outh, "} %s;\n", type);
4320 str = make_pre_macro (fnode->ftype, "TYPE");
4321 out_printf (outh, "#define %s ", str);
4324 out_printf (outh, "%s_get_type()\n", funcprefix);
4325 out_printf (outh, "GType %s_get_type (void) G_GNUC_CONST;\n\n", funcprefix);
4328 "GType\n%s_get_type (void)\n"
4330 "\tstatic GType type = 0;\n"
4331 "\tif ___GOB_UNLIKELY(type == 0)\n"
4332 "\t\ttype = g_flags_register_static (\"%s\", _%s_values);\n"
4335 funcprefix, type, funcprefix);
4337 g_free (funcprefix);
4342 print_error (Error *enode)
4349 funcprefix = replace_sep (enode->etype, '_');
4350 gob_strdown (funcprefix);
4351 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
4353 type = remove_sep (enode->etype);
4355 out_printf (outh, "\ntypedef enum {\n");
4357 for (li = enode->values; li != NULL; li = li->next) {
4358 const char *name = li->data;
4360 char *sname = gob_strdown (g_strdup (name));
4362 while ((p = strchr (sname, '_')) != NULL)
4365 out_printf (outh, "\t%s_%s", enode->prefix, name);
4366 if (li->next != NULL)
4367 out_printf (outh, ",\n");
4369 out_printf (outh, "\n");
4371 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
4372 enode->prefix, name,
4373 enode->prefix, name,
4379 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
4381 out_printf (outh, "} %s;\n", type);
4383 str = make_pre_macro (enode->etype, "TYPE");
4384 out_printf (outh, "#define %s ", str);
4387 out_printf (outh, "%s_get_type ()\n", funcprefix);
4388 out_printf (outh, "GType %s_get_type (void) G_GNUC_CONST;\n\n", funcprefix);
4391 "GType\n%s_get_type (void)\n"
4393 "\tstatic GType type = 0;\n"
4394 "\tif ___GOB_UNLIKELY(type == 0)\n"
4395 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
4398 funcprefix, type, funcprefix);
4400 out_printf (outh, "#define %s %s_quark ()\n", enode->prefix, funcprefix);
4401 out_printf (outh, "GQuark %s_quark (void);\n\n", funcprefix);
4403 str = replace_sep (enode->etype, '-');
4407 "GQuark\n%s_quark (void)\n"
4409 "\tstatic GQuark q = 0;\n"
4411 "\t\tq = g_quark_from_static_string (\"%s\");\n"
4418 g_free (funcprefix);
4423 generate_outfiles(void)
4427 print_file_comments();
4433 print_header_prefixes();
4435 print_useful_macros();
4439 print_more_useful_macros ();
4441 for (li = nodes; li != NULL; li = li->next) {
4442 Node *node = li->data;
4443 if (node->type == CCODE_NODE) {
4444 CCode *cc = (CCode *)node;
4445 if (cc->cctype != HT_CCODE &&
4446 cc->cctype != AT_CCODE &&
4447 cc->cctype != AD_CCODE)
4448 print_ccode_block ((CCode *)node);
4449 } else if (node->type == CLASS_NODE) {
4450 print_class_block ((Class *)node);
4451 } else if (node->type == ENUMDEF_NODE) {
4452 print_enum ((EnumDef *)node);
4453 } else if (node->type == FLAGS_NODE) {
4454 print_flags ((Flags *)node);
4455 } else if (node->type == ERROR_NODE) {
4456 print_error ((Error *)node);
4458 g_assert_not_reached();
4462 print_header_postfixes();
4468 fprintf(stderr, "Gob version %s\n\n", VERSION);
4469 fprintf(stderr, "gob [options] file.gob\n\n");
4470 fprintf(stderr, "Options:\n"
4471 "\t--help,-h,-? Display this help\n"
4472 "\t--version Display version\n"
4473 "\t--exit-on-warn,-w Exit with an error on warnings\n"
4474 "\t--no-exit-on-warn Don't exit on warnings [default]\n"
4475 "\t--for-cpp Create C++ files\n"
4476 "\t--no-extern-c Never print extern \"C\" into the "
4478 "\t--no-gnu Never use GNU extentions\n"
4479 "\t--no-touch Don't touch output files unless they "
4481 "\t changed (implies --no-touch-headers)\n"
4482 "\t--no-touch-headers Don't touch headers unless they "
4484 "\t--always-private-header Always create a private header "
4486 "\t even if it would be empty\n"
4487 "\t--ondemand-private-header Create private header only when "
4490 "\t--no-private-header Don't create a private header, "
4492 "\t structure and protected "
4493 "prototypes inside c file\n"
4494 "\t--always-private-struct Always create a private pointer "
4496 "\t the object structure\n"
4497 "\t--m4 Preprocess source with m4. "
4498 "Following args will\n"
4499 "\t be passed to m4\n"
4500 "\t--m4-dir Print directory that will be "
4503 "\t--no-write,-n Don't write output files, just "
4505 "\t--no-lines Don't print '#line' to output\n"
4506 "\t--no-self-alias Don't create self type and macro "
4508 "\t--no-kill-underscores Ignored for compatibility\n"
4509 "\t-o,--output-dir The directory where output "
4510 "should be placed\n"
4511 "\t--file-sep[=c] replace default \'-\' file "
4512 "name separator\n\n"
4513 "\t--gtk3 Use gtk+3\n"
4515 fprintf(stderr, "End world hunger, donate to the World Food Programme, http://www.wfp.org\n");
4519 parse_options(int argc, char *argv[])
4522 int got_file = FALSE;
4523 int no_opts = FALSE;
4524 int m4_opts = FALSE; /* if we are just passing on args to m4 */
4528 for(i = 1 ; i < argc; i++) {
4530 char *new_commandline;
4531 g_assert(m4_commandline!=NULL);
4533 /* check whether this one looks like the filename */
4534 if((!strcmp(argv[i],"-") || argv[i][0] != '-')
4536 const gchar *m4_flags=use_m4_clean?"":M4_FLAGS;
4540 /* insert flags before the filename */
4541 new_commandline=g_strconcat(m4_commandline,
4549 /* just an ordinary option */
4551 new_commandline=g_strconcat(m4_commandline,
4556 /* free old commandline */
4557 g_free(m4_commandline);
4558 m4_commandline=new_commandline;
4560 } else if(no_opts ||
4561 argv[i][0] != '-') {
4564 fprintf(stderr, "Specify only one file!\n");
4570 } else if(strcmp(argv[i], "--help")==0) {
4573 } else if(strcmp(argv[i], "--version")==0) {
4574 fprintf(stderr, "Gob version %s\n", VERSION);
4576 } else if(strcmp(argv[i], "--exit-on-warn")==0) {
4577 exit_on_warn = TRUE;
4578 } else if(strcmp(argv[i], "--no-exit-on-warn")==0) {
4579 exit_on_warn = FALSE;
4580 } else if(strcmp(argv[i], "--for-cpp")==0) {
4582 } else if(strcmp(argv[i], "--no-touch")==0) {
4584 no_touch_headers = TRUE;
4585 } else if(strcmp(argv[i], "--no-touch-headers")==0) {
4586 no_touch_headers = TRUE;
4587 } else if(strcmp(argv[i], "--ondemand-private-header")==0) {
4588 private_header = PRIVATE_HEADER_ONDEMAND;
4589 } else if(strcmp(argv[i], "--always-private-header")==0) {
4590 private_header = PRIVATE_HEADER_ALWAYS;
4591 } else if(strcmp(argv[i], "--no-private-header")==0) {
4592 private_header = PRIVATE_HEADER_NEVER;
4593 } else if(strcmp(argv[i], "--no-gnu")==0) {
4595 } else if(strcmp(argv[i], "--no-extern-c")==0) {
4597 } else if(strcmp(argv[i], "--no-write")==0) {
4599 } else if(strcmp(argv[i], "--no-lines")==0) {
4601 } else if(strcmp(argv[i], "--no-self-alias")==0) {
4602 no_self_alias = TRUE;
4603 } else if(strcmp(argv[i], "--no-kill-underscores")==0) {
4605 } else if(strcmp(argv[i], "--always-private-struct")==0) {
4606 always_private_struct = TRUE;
4607 } else if(strcmp(argv[i], "--m4-dir")==0) {
4608 printf("%s\n",M4_INCLUDE_DIR);
4610 } else if(strcmp(argv[i], "--m4")==0) {
4614 m4_commandline=g_strdup(M4_COMMANDLINE);
4615 } else if(strcmp(argv[i], "--m4-clean")==0) {
4619 m4_commandline=g_strdup(M4_COMMANDLINE);
4620 } else if (strcmp (argv[i], "-o") == 0 ||
4621 strcmp (argv[i], "--output-dir") == 0) {
4623 output_dir = g_strdup (argv[i+1]);
4628 } else if (strncmp (argv[i], "-o=", strlen ("-o=")) == 0 ||
4631 strlen ("--output-dir=")) == 0) {
4632 char *p = strchr (argv[i], '=');
4633 g_assert (p != NULL);
4634 output_dir = g_strdup (p+1);
4635 } else if (strncmp (argv[i], "--file-sep=",
4636 strlen ("--file-sep=")) == 0) {
4637 char *p = strchr (argv[i], '=');
4638 g_assert (p != NULL);
4640 } else if (strncmp (argv[i], "--file-sep",
4641 strlen ("--file-sep")) == 0) {
4643 file_sep = (argv[i+1])[0];
4648 } else if(strcmp(argv[i], "--gtk3")==0) {
4650 } else if(strcmp(argv[i], "--")==0) {
4651 /*further arguments are files*/
4653 } else if(strncmp(argv[i], "--", 2)==0) {
4654 /*unknown long option*/
4655 fprintf(stderr, "Unknown option '%s'!\n", argv[i]);
4659 /*by now we know we have a string starting with
4660 - which is a short option string*/
4662 for(p = argv[i] + 1; *p; p++) {
4676 "Unknown option '%c'!\n", *p);
4685 /* if we are using m4, and got no filename, append m4 flags now */
4686 if(!got_file && use_m4 && !use_m4_clean) {
4687 char *new_commandline;
4688 new_commandline=g_strconcat(m4_commandline,
4692 g_free(m4_commandline);
4693 m4_commandline=new_commandline;
4699 compare_and_move (const char *old_filename)
4701 char *new_filename = g_strconcat (old_filename, "#gob#", NULL);
4703 gboolean equal = FALSE;
4705 old_f = fopen (old_filename, "r");
4708 gboolean error = FALSE;
4710 new_f = fopen (new_filename, "r");
4719 new_n = fread (new_buf, 1, sizeof (new_buf), new_f);
4720 if (ferror (new_f)) {
4722 error_printf (GOB_ERROR, 0,
4723 "Can't read %s: %s",
4725 g_strerror (errno));
4729 old_n = fread (old_buf, 1, sizeof (old_buf), old_f);
4731 || feof (new_f) != feof (old_f)
4733 || memcmp (new_buf, old_buf, new_n) != 0)
4742 error_printf (GOB_ERROR, 0, "Can't open %s: %s",
4743 new_filename, g_strerror (errno));
4751 if (! equal && unlink (old_filename) != 0) {
4752 error_printf (GOB_ERROR, 0, "Can't remove %s: %s",
4753 old_filename, g_strerror (errno));
4759 if (unlink (new_filename) != 0)
4760 error_printf (GOB_ERROR, 0, "Can't remove %s: %s",
4761 new_filename, g_strerror (errno));
4763 if (rename (new_filename, old_filename) != 0)
4764 error_printf (GOB_ERROR, 0, "Can't rename %s to %s: %s",
4765 new_filename, old_filename,
4766 g_strerror (errno));
4770 g_free (new_filename);
4774 main(int argc, char *argv[])
4776 parse_options(argc, argv);
4779 yyin = popen(m4_commandline, "r");
4781 fprintf(stderr, "Error: can't open pipe from '%s'\n",
4785 } else if(filename) {
4786 yyin = fopen(filename, "r");
4788 fprintf(stderr, "Error: can't open file '%s'\n",
4797 /* This is where parsing is done */
4800 error_print (GOB_ERROR, 0, "Parsing errors, quitting");
4802 /* close input file */
4803 if(use_m4) pclose(yyin);
4808 error_print (GOB_ERROR, 0, "no class defined");
4811 exit_on_error = FALSE;
4813 signals = count_signals ((Class *)class);
4814 set_properties = count_set_properties ((Class *)class) +
4815 count_set_arguments ((Class *)class);
4816 get_properties = count_get_properties ((Class *)class) +
4817 count_get_arguments ((Class *)class);
4818 overrides = count_overrides ((Class *)class);
4819 privates = count_privates ((Class *)class);
4820 protecteds = count_protecteds ((Class *)class);
4821 unreftors = count_unreftors ((Class *)class);
4822 destructors = count_destructors ((Class *)class);
4823 initializers = count_initializers ((Class *)class);
4824 glade_widgets = count_glade_widgets ((Class *)class);
4825 overrode_get_type = find_get_type ((Class *)class);
4828 make_inits ((Class *)class);
4830 find_constructor ((Class *)class);
4831 if (user_constructor != NULL)
4832 need_constructor = TRUE;
4834 find_dispose ((Class *)class);
4835 if (unreftors > 0 ||
4836 dispose_handler != NULL ||
4837 user_dispose_method != NULL)
4838 need_dispose = TRUE;
4840 find_finalize ((Class *)class);
4841 if (destructors > 0 ||
4843 user_finalize_method != NULL) {
4844 need_finalize = TRUE;
4847 check_bad_symbols ((Class *)class);
4848 check_duplicate_symbols ((Class *)class);
4849 check_duplicate_overrides ((Class *)class);
4850 check_duplicate_signals_args ((Class *)class);
4851 check_public_new ((Class *)class);
4852 check_vararg ((Class *)class);
4853 check_firstarg ((Class *)class);
4854 check_nonvoidempty ((Class *)class);
4855 check_signal_args ((Class *)class);
4856 check_property_types ((Class *)class);
4857 check_argument_types ((Class *)class);
4858 check_func_arg_checks ((Class *)class);
4859 check_func_attrs ((Class *)class);
4860 check_for_class_destructors ((Class *)class);
4862 exit_on_error = TRUE;
4867 any_special = setup_special_array ((Class *)class, special_array);
4871 generate_outfiles ();
4882 compare_and_move (outfilebase);
4884 compare_and_move (outfilephbase);
4886 if (no_touch_headers)
4887 compare_and_move (outfilehbase);