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 define_add_privates(Class *c)
1233 const char *addprivate = c->dynamic
1234 ? "G_ADD_PRIVATE_DYNAMIC"
1240 out_printf(out, "#ifdef %s\n"
1241 "#define ___add_privates() %s(%s)\n"
1243 "#define ___add_privates()\n"
1245 addprivate, addprivate, typebase);
1248 static void add_type_info(void)
1250 out_printf(out, "\tstatic const GTypeInfo info = {\n"
1251 "\t\tsizeof (%sClass),\n"
1252 "\t\t(GBaseInitFunc) NULL,\n"
1253 "\t\t(GBaseFinalizeFunc) NULL,\n"
1254 "\t\t(GClassInitFunc) %s_class_init,\n"
1255 "\t\t(GClassFinalizeFunc) NULL,\n"
1256 "\t\tNULL /* class_data */,\n"
1257 "\t\tsizeof (%s),\n"
1258 "\t\t%d /* n_preallocs */,\n"
1259 "\t\t(GInstanceInitFunc) %s_init,\n"
1262 typebase, funcbase, typebase, prealloc, funcbase);
1268 Class *c = (Class *)class;
1270 define_add_interfaces(c);
1271 define_add_privates(c);
1273 out_printf(out, "#ifdef G_DEFINE_TYPE_EXTENDED\n\n"
1274 "G_DEFINE_TYPE_EXTENDED(%s, %s, %s,\n"
1275 "\t(GTypeFlags)%s,\n",
1276 typebase, funcbase, pmacrotype,
1277 c->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0");
1280 out_printf(out, "\t___add_privates();\n");
1283 out_printf(out, "\t___add_interfaces(g_define_type_id);\n");
1285 /* Fallback for GLib < 2.4 */
1286 out_printf(out, ");\n\n"
1288 "GType %s_get_type(void)\n"
1290 "\tstatic GType type = 0;\n",
1295 out_printf(out, "\tif ___GOB_UNLIKELY(type == 0) {\n"
1296 "\t\ttype = g_type_register_static\n"
1300 "\t\t\t, (GTypeFlags)%s\n"
1302 pmacrotype, typebase,
1303 c->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0");
1306 out_printf(out, "\t\t___add_interfaces(type);\n");
1308 out_printf(out, "\t}\n\n"
1315 add_dynamic_get_type(void)
1317 Class *c = (Class *)class;
1319 define_dynamic_add_interfaces(c);
1320 define_add_privates(c);
1323 * G_DEFINE_DYNAMIC_TYPE_EXTENDED is usable if available, except for
1324 * some reason it defines an xxx_register_type function with internal
1325 * linkage. This is kind of weird so we have to work around that.
1327 out_printf(out, "#ifdef G_DEFINE_DYNAMIC_TYPE_EXTENDED\n\n"
1328 "static void %s_class_finalize(%sClass *c) { }\n\n"
1329 "#define %s_register_type ___register_type\n",
1330 funcbase, typebase, funcbase);
1332 out_printf(out, "G_DEFINE_DYNAMIC_TYPE_EXTENDED(%s, %s, %s,\n"
1333 "\t(GTypeFlags)%s,\n",
1334 typebase, funcbase, pmacrotype,
1335 c->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0");
1338 out_printf(out, "\t___add_privates();\n");
1340 if (c->interfaces) {
1341 out_printf(out, "\t___add_interfaces"
1342 "(type_module, %s_type_id);\n", funcbase);
1345 out_printf(out, ");\n"
1346 "#undef %s_register_type\n\n"
1347 "void %s_register_type(GTypeModule *type_module)\n"
1349 "\t___register_type(type_module);\n"
1351 funcbase, funcbase);
1353 /* Fallback for GLib < 2.14 */
1354 out_printf(out, "#else\n\n"
1355 "static GType %s_type_id;\n\n"
1356 "GType %s_get_type(void)\n"
1358 "\treturn %s_type_id;\n"
1360 funcbase, funcbase, funcbase);
1362 out_printf(out, "void %s_register_type(GTypeModule *type_module)\n"
1368 out_printf(out, "\t%s_type_id = g_type_module_register_type\n"
1369 "\t\t( type_module\n"
1373 "\t\t, (GTypeFlags)%s\n"
1375 funcbase, pmacrotype, typebase,
1376 c->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0");
1378 if (c->interfaces) {
1379 out_printf(out, "\t___add_interfaces"
1380 "(type_module, %s_type_id);\n",
1384 out_printf(out, "}\n\n"
1389 add_bonobo_object_get_type(void)
1391 Class *c = (Class *)class;
1393 define_add_interfaces(c);
1395 out_printf (out, "GType %s_get_type(void)\n"
1397 "\tstatic GType type = 0;\n",
1402 out_printf (out, "\tif ___GOB_UNLIKELY(type == 0) {\n"
1403 "\t\ttype = bonobo_type_unique\n"
1404 "\t\t\t( BONOBO_OBJECT_TYPE\n"
1405 "\t\t\t, POA_%s__init, NULL\n"
1406 "\t\t\t, G_STRUCT_OFFSET (%sClass, _epv)\n"
1410 c->bonobo_object_class, typebase, typebase);
1412 if (((Class *)class)->interfaces)
1413 out_printf(out, "\t\t___add_interfaces(type);\n");
1415 out_printf(out, "\t}\n\n"
1421 add_overrides(Class *c, const char *oname,
1422 gboolean did_base_obj)
1428 done = g_hash_table_new (g_str_hash, g_str_equal);
1430 s = g_strdup ("GObject");
1431 g_hash_table_insert (done, s, s);
1433 for (li = c->nodes; li != NULL; li = li->next) {
1436 Method *m = (Method *)n;
1437 if(n->type != METHOD_NODE ||
1438 m->method != OVERRIDE_METHOD)
1441 s = remove_sep(m->otype);
1443 if(g_hash_table_lookup(done, s)) {
1447 g_hash_table_insert(done, s, s);
1449 f = replace_sep(m->otype, '_');
1452 out_printf(out, "\t%sClass *%s_class = (%sClass *)%s;\n",
1457 g_hash_table_foreach (done, (GHFunc)g_free, NULL);
1458 g_hash_table_destroy (done);
1462 make_run_signal_flags(Method *m, gboolean last)
1477 gs = g_string_new(NULL);
1480 g_string_assign(gs, "G_SIGNAL_RUN_LAST");
1482 g_string_assign(gs, "G_SIGNAL_RUN_FIRST");
1484 if(m->scope == PUBLIC_SCOPE)
1485 g_string_append(gs, " | G_SIGNAL_ACTION");
1487 for(li = m->flags; li; li = li->next) {
1488 char *flag = li->data;
1490 for(i=0;flags[i];i++) {
1491 if(strcmp(flags[i], flag)==0)
1494 /* if we haven't found it in our list */
1496 error_printf(GOB_WARN, m->line_no,
1497 "Unknown flag '%s' used, "
1498 "perhaps it was misspelled",
1501 g_string_sprintfa(gs, " | G_SIGNAL_%s", flag);
1505 char *ret = gs->str;
1506 g_string_free(gs, FALSE);
1513 add_signals(Class *c)
1517 out_printf(out, "\n");
1518 for(li=c->nodes;li;li=g_list_next(li)) {
1520 char *mar, *sig, *flags;
1521 gboolean is_none, last = FALSE;
1522 Method *m = (Method *)n;
1524 if(n->type != METHOD_NODE ||
1525 (m->method != SIGNAL_FIRST_METHOD &&
1526 m->method != SIGNAL_LAST_METHOD))
1529 if(m->method == SIGNAL_FIRST_METHOD)
1534 if(g_hash_table_lookup(marsh, m))
1535 mar = g_strconcat("___marshal_",
1536 (char *)g_hash_table_lookup(marsh, m),
1539 mar = g_strdup("g_cclosure_marshal_VOID__VOID");
1541 is_none = (strcmp(m->gtktypes->next->data, "NONE")==0);
1543 sig = g_strdup (m->id);
1545 flags = make_run_signal_flags (m, last);
1546 out_printf (out, "\tobject_signals[%s_SIGNAL] =\n"
1547 "\t\tg_signal_new (%s,\n"
1548 "\t\t\tG_TYPE_FROM_CLASS (g_object_class),\n"
1549 "\t\t\t(GSignalFlags)(%s),\n"
1550 "\t\t\tG_STRUCT_OFFSET (%sClass, %s),\n"
1551 "\t\t\tNULL, NULL,\n"
1553 "\t\t\tG_TYPE_%s, %d",
1554 sig, m->signal_name /*m->id* if not given signal_name*/,
1556 typebase, m->id, mar,
1557 (char *)m->gtktypes->data,
1558 is_none ? 0 : g_list_length(m->gtktypes->next));
1566 for(l = m->gtktypes->next; l != NULL; l = l->next) {
1567 char *str = l->data;
1568 if (strncmp (str, "BOXED_", 6) == 0)
1569 t = g_strdup (&(str[6]));
1571 t = g_strconcat ("G_TYPE_", str, NULL);
1572 out_printf (out, ",\n\t\t\t%s", t);
1577 out_printf(out, ");\n");
1579 if(strcmp(m->gtktypes->data, "NONE") != 0 ||
1582 out_printf(out, "\tif ___GOB_UNLIKELY(");
1583 if(strcmp(m->gtktypes->data, "NONE") != 0) {
1584 out_printf(out, "sizeof(");
1585 print_type(out, m->mtype, FALSE);
1586 out_printf(out, "%s",
1588 m->mtype->postfix : "");
1589 out_printf(out, ") != sizeof(%s) || ",
1590 get_cast(m->gtktypes->data, FALSE));
1593 for(al = m->args->next, gl = m->gtktypes->next;
1594 al != NULL && gl != NULL;
1595 al = al->next, gl = gl->next) {
1596 FuncArg *arg = al->data;
1597 char *gtkarg = gl->data;
1599 out_printf(out, "sizeof(");
1600 print_type(out, arg->atype, FALSE);
1601 out_printf(out, "%s",
1602 arg->atype->postfix ?
1603 arg->atype->postfix : "");
1604 out_printf(out, ") != sizeof(%s) || ",
1605 get_cast(gtkarg, FALSE));
1609 "parent_class == NULL /* avoid warning */");
1611 out_printf(out, ") {\n"
1612 "\t\tg_error(\"%s line %d: Type mismatch "
1613 "of \\\"%s\\\" signal signature\");\n"
1615 filename, m->line_no, m->id);
1622 set_def_handlers(Class *c, const char *oname)
1625 gboolean set_line = FALSE;
1627 out_printf(out, "\n");
1628 for(li = c->nodes; li; li = g_list_next(li)) {
1630 Method *m = (Method *)n;
1632 if(n->type != METHOD_NODE ||
1633 (m->method != SIGNAL_FIRST_METHOD &&
1634 m->method != SIGNAL_LAST_METHOD &&
1635 m->method != VIRTUAL_METHOD &&
1636 m->method != OVERRIDE_METHOD))
1639 if(m->line_no > 0 && m->cbuf) {
1640 out_addline_infile(out, m->line_no);
1642 } else if(set_line) {
1643 out_addline_outfile(out);
1648 if (m->method == OVERRIDE_METHOD) {
1650 s = replace_sep (m->otype, '_');
1654 dispose_handler != NULL &&
1655 strcmp (m->id, "dispose") == 0)
1656 out_printf (out, "\tg_object_class->dispose "
1658 else if (need_finalize &&
1660 strcmp(m->id, "finalize") == 0)
1662 "\tg_object_class->finalize = ___finalize;\n");
1663 else if (m->cbuf != NULL)
1665 "\t%s_class->%s = ___%x_%s_%s;\n",
1666 s, m->id, (guint)m->unique_id,
1669 out_printf(out, "\t%s_class->%s = NULL;\n",
1673 out_printf(out, "\t%s->%s = ___real_%s_%s;\n",
1677 out_printf(out, "\t%s->%s = NULL;\n",
1682 out_addline_outfile(out);
1686 make_argument (Argument *a)
1691 char *argflags[] = {
1699 flags = g_string_new ("(GParamFlags)(");
1701 if(a->get && a->set)
1702 g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
1704 g_string_append (flags, "G_PARAM_READABLE");
1706 g_string_append (flags, "G_PARAM_WRITABLE");
1708 g_assert(a->get || a->set);
1710 for (l = a->flags; l != NULL; l = l->next) {
1711 char *flag = l->data;
1713 if(strcmp (flag, "READABLE") == 0 ||
1714 strcmp (flag, "WRITABLE") == 0) {
1715 error_print(GOB_WARN, a->line_no,
1717 "WRITABLE argument flags are "
1718 "set automatically");
1721 for(i = 0; argflags[i]; i++) {
1722 if(strcmp(argflags[i], flag)==0)
1725 g_string_sprintfa(flags, " | %s%s", argflags[i] ? "G_PARAM_" : "", flag);
1728 g_string_append (flags, ")");
1730 s = g_strdup(a->name);
1732 if (!strcmp (a->gtktype, "ENUM"))
1733 out_printf(out, "\tparam_spec = g_param_spec_enum (\"%s\", NULL, NULL,\n"
1734 "\t\tG_TYPE_ENUM, 0,\n"
1736 a->name, flags->str);
1737 if (!strcmp (a->gtktype, "FLAGS"))
1738 out_printf(out, "\tparam_spec = g_param_spec_flags (\"%s\", NULL, NULL,\n"
1739 "\t\tG_TYPE_FLAGS, 0,\n"
1741 a->name, flags->str);
1742 else if (!strcmp (a->gtktype, "OBJECT"))
1743 out_printf(out, "\tparam_spec = g_param_spec_object (\"%s\", NULL, NULL,\n"
1744 "\t\tG_TYPE_OBJECT,\n"
1746 a->name, flags->str);
1747 else if (!strcmp (a->gtktype, "STRING"))
1748 out_printf(out, "\tparam_spec = g_param_spec_string (\"%s\", NULL, NULL,\n"
1751 a->name, flags->str);
1752 else if (!strcmp (a->gtktype, "INT"))
1753 out_printf(out, "\tparam_spec = g_param_spec_int (\"%s\", NULL, NULL,\n"
1754 "\t\tG_MININT, G_MAXINT,\n"
1757 a->name, flags->str);
1758 else if (!strcmp (a->gtktype, "UINT"))
1759 out_printf(out, "\tparam_spec = g_param_spec_uint (\"%s\", NULL, NULL,\n"
1760 "\t\t0, G_MAXUINT,\n"
1763 a->name, flags->str);
1764 else if (!strcmp (a->gtktype, "INT"))
1765 out_printf(out, "\tparam_spec = g_param_spec_int (\"%s\", NULL, NULL,\n"
1766 "\t\tG_MININT, G_MAXINT,\n"
1769 a->name, flags->str);
1770 else if (!strcmp (a->gtktype, "CHAR"))
1771 out_printf(out, "\tparam_spec = g_param_spec_char (\"%s\", NULL, NULL,\n"
1775 a->name, flags->str);
1776 else if (!strcmp (a->gtktype, "UCHAR"))
1777 out_printf(out, "\tparam_spec = g_param_spec_uchar (\"%s\", NULL, NULL,\n"
1781 a->name, flags->str);
1782 else if (!strcmp (a->gtktype, "BOOL") ||
1783 !strcmp (a->gtktype, "BOOLEAN"))
1784 out_printf(out, "\tparam_spec = g_param_spec_boolean (\"%s\", NULL, NULL,\n"
1787 a->name, flags->str);
1788 else if (!strcmp (a->gtktype, "LONG"))
1789 out_printf(out, "\tparam_spec = g_param_spec_long (\"%s\", NULL, NULL,\n"
1790 "\t\tG_MINLONG, G_MAXLONG,\n"
1793 a->name, flags->str);
1794 else if (!strcmp (a->gtktype, "ULONG"))
1795 out_printf(out, "\tparam_spec = g_param_spec_ulong (\"%s\", NULL, NULL,\n"
1796 "\t\t0, G_MAXULONG,\n"
1799 a->name, flags->str);
1800 else if (!strcmp (a->gtktype, "INT64"))
1801 out_printf(out, "\tparam_spec = g_param_spec_int64 (\"%s\", NULL, NULL,\n"
1802 "\t\tG_MININT64, G_MAXINT64,\n"
1805 a->name, flags->str);
1806 else if (!strcmp (a->gtktype, "UINT64"))
1807 out_printf(out, "\tparam_spec = g_param_spec_uint64 (\"%s\", NULL, NULL,\n"
1808 "\t\t0, G_MAXUINT64,\n"
1811 a->name, flags->str);
1812 else if (!strcmp (a->gtktype, "FLOAT"))
1813 out_printf(out, "\tparam_spec = g_param_spec_float (\"%s\", NULL, NULL,\n"
1814 "\t\t-G_MAXFLOAT, G_MAXFLOAT,\n"
1817 a->name, flags->str);
1818 else if (!strcmp (a->gtktype, "DOUBLE"))
1819 out_printf(out, "\tparam_spec = g_param_spec_double (\"%s\", NULL, NULL,\n"
1820 "\t\t-G_MAXDOUBLE, G_MAXDOUBLE,\n"
1823 a->name, flags->str);
1824 else if (!strcmp (a->gtktype, "POINTER"))
1825 out_printf(out, "\tparam_spec = g_param_spec_pointer (\"%s\", NULL, NULL,\n"
1827 a->name, flags->str);
1829 error_printf (GOB_ERROR, a->line_no,
1830 "%s type is not supported for arguments, try using properties",
1833 out_printf(out, "\tg_object_class_install_property (g_object_class,\n"
1834 "\t\tPROP_%s, param_spec);\n", s);
1838 g_string_free(flags, TRUE);
1841 #define value_for_print(str, alt) (str != NULL ? str : alt)
1844 make_property (Property *p)
1848 if (p->get == NULL && p->set == NULL) {
1849 error_print (GOB_ERROR, p->line_no,
1850 "Property has no getter nor setter");
1854 if (p->flags != NULL)
1855 error_print (GOB_WARN, p->line_no,
1856 "Overridden property, flags ignored");
1857 if (p->nick != NULL)
1858 error_print (GOB_WARN, p->line_no,
1859 "Overridden property, nick ignored");
1860 if (p->blurb != NULL)
1861 error_print (GOB_WARN, p->line_no,
1862 "Overridden property, blurb ignored");
1863 if (p->minimum != NULL)
1864 error_print (GOB_WARN, p->line_no,
1865 "Overridden property, minimum ignored");
1866 if (p->maximum != NULL)
1867 error_print (GOB_WARN, p->line_no,
1868 "Overridden property, maximum ignored");
1869 if (p->default_value != NULL)
1870 error_print (GOB_WARN, p->line_no,
1871 "Overridden property, default_value ignored");
1873 s = g_strdup (p->name);
1875 out_printf (out, "\tg_object_class_override_property (g_object_class,\n"
1877 "\t\t\"%s\");\n", s, value_for_print (p->canonical_name, p->name) );
1882 char *argflags[] = {
1890 flags = g_string_new ("(GParamFlags)(");
1892 if (p->get != NULL && p->set != NULL)
1893 g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
1894 else if (p->get != NULL)
1895 g_string_append (flags, "G_PARAM_READABLE");
1897 g_string_append (flags, "G_PARAM_WRITABLE");
1900 for (l = p->flags; l != NULL; l = l->next) {
1901 char *flag = l->data;
1903 if(strcmp (flag, "READABLE") == 0 ||
1904 strcmp (flag, "WRITABLE") == 0) {
1905 error_print(GOB_WARN, p->line_no,
1907 "WRITABLE argument flags are "
1908 "set automatically");
1911 for(i = 0; argflags[i]; i++) {
1912 if(strcmp(argflags[i], flag)==0)
1915 g_string_sprintfa(flags, " | %s%s", argflags[i] ? "G_PARAM_" : "", flag);
1918 g_string_append (flags, ")");
1920 if (strcmp (p->gtktype, "CHAR") == 0) {
1921 out_printf (out, "\tparam_spec = g_param_spec_char\n"
1922 "\t\t(\"%s\" /* name */,\n"
1923 "\t\t %s /* nick */,\n"
1924 "\t\t %s /* blurb */,\n"
1925 "\t\t %s /* minimum */,\n"
1926 "\t\t %s /* maximum */,\n"
1927 "\t\t %s /* default_value */,\n"
1929 value_for_print (p->canonical_name, p->name),
1930 value_for_print (p->nick, "NULL"),
1931 value_for_print (p->blurb, "NULL"),
1932 value_for_print (p->minimum, "-128"),
1933 value_for_print (p->maximum, "127"),
1934 value_for_print (p->default_value, "0"),
1936 } else if (strcmp (p->gtktype, "UCHAR") == 0) {
1937 out_printf (out, "\tparam_spec = g_param_spec_uchar\n"
1938 "\t\t(\"%s\" /* name */,\n"
1939 "\t\t %s /* nick */,\n"
1940 "\t\t %s /* blurb */,\n"
1941 "\t\t %s /* minimum */,\n"
1942 "\t\t %s /* maximum */,\n"
1943 "\t\t %s /* default_value */,\n"
1945 value_for_print (p->canonical_name, p->name),
1946 value_for_print (p->nick, "NULL"),
1947 value_for_print (p->blurb, "NULL"),
1948 value_for_print (p->minimum, "0"),
1949 value_for_print (p->maximum, "0xFF"),
1950 value_for_print (p->default_value, "0"),
1952 } else if (strcmp (p->gtktype, "BOOLEAN") == 0) {
1953 out_printf (out, "\tparam_spec = g_param_spec_boolean\n"
1954 "\t\t(\"%s\" /* name */,\n"
1955 "\t\t %s /* nick */,\n"
1956 "\t\t %s /* blurb */,\n"
1957 "\t\t %s /* default_value */,\n"
1959 value_for_print (p->canonical_name, p->name),
1960 value_for_print (p->nick, "NULL"),
1961 value_for_print (p->blurb, "NULL"),
1962 value_for_print (p->default_value, "FALSE"),
1964 } else if (strcmp (p->gtktype, "INT") == 0) {
1965 out_printf (out, "\tparam_spec = g_param_spec_int\n"
1966 "\t\t(\"%s\" /* name */,\n"
1967 "\t\t %s /* nick */,\n"
1968 "\t\t %s /* blurb */,\n"
1969 "\t\t %s /* minimum */,\n"
1970 "\t\t %s /* maximum */,\n"
1971 "\t\t %s /* default_value */,\n"
1973 value_for_print (p->canonical_name, p->name),
1974 value_for_print (p->nick, "NULL"),
1975 value_for_print (p->blurb, "NULL"),
1976 value_for_print (p->minimum, "G_MININT"),
1977 value_for_print (p->maximum, "G_MAXINT"),
1978 value_for_print (p->default_value, "0"),
1980 } else if (strcmp (p->gtktype, "UINT") == 0) {
1981 out_printf (out, "\tparam_spec = g_param_spec_uint\n"
1982 "\t\t(\"%s\" /* name */,\n"
1983 "\t\t %s /* nick */,\n"
1984 "\t\t %s /* blurb */,\n"
1985 "\t\t %s /* minimum */,\n"
1986 "\t\t %s /* maximum */,\n"
1987 "\t\t %s /* default_value */,\n"
1989 value_for_print (p->canonical_name, p->name),
1990 value_for_print (p->nick, "NULL"),
1991 value_for_print (p->blurb, "NULL"),
1992 value_for_print (p->minimum, "0"),
1993 value_for_print (p->maximum, "G_MAXUINT"),
1994 value_for_print (p->default_value, "0"),
1996 } else if (strcmp (p->gtktype, "LONG") == 0) {
1997 out_printf (out, "\tparam_spec = g_param_spec_long\n"
1998 "\t\t(\"%s\" /* name */,\n"
1999 "\t\t %s /* nick */,\n"
2000 "\t\t %s /* blurb */,\n"
2001 "\t\t %s /* minimum */,\n"
2002 "\t\t %s /* maximum */,\n"
2003 "\t\t %s /* default_value */,\n"
2005 value_for_print (p->canonical_name, p->name),
2006 value_for_print (p->nick, "NULL"),
2007 value_for_print (p->blurb, "NULL"),
2008 value_for_print (p->minimum, "G_MINLONG"),
2009 value_for_print (p->maximum, "G_MAXLONG"),
2010 value_for_print (p->default_value, "0"),
2012 } else if (strcmp (p->gtktype, "ULONG") == 0) {
2013 out_printf (out, "\tparam_spec = g_param_spec_ulong\n"
2014 "\t\t(\"%s\" /* name */,\n"
2015 "\t\t %s /* nick */,\n"
2016 "\t\t %s /* blurb */,\n"
2017 "\t\t %s /* minimum */,\n"
2018 "\t\t %s /* maximum */,\n"
2019 "\t\t %s /* default_value */,\n"
2021 value_for_print (p->canonical_name, p->name),
2022 value_for_print (p->nick, "NULL"),
2023 value_for_print (p->blurb, "NULL"),
2024 value_for_print (p->minimum, "0"),
2025 value_for_print (p->maximum, "G_MAXULONG"),
2026 value_for_print (p->default_value, "0"),
2028 } else if (strcmp (p->gtktype, "INT64") == 0) {
2029 out_printf (out, "\tparam_spec = g_param_spec_int64\n"
2030 "\t\t(\"%s\" /* name */,\n"
2031 "\t\t %s /* nick */,\n"
2032 "\t\t %s /* blurb */,\n"
2033 "\t\t %s /* minimum */,\n"
2034 "\t\t %s /* maximum */,\n"
2035 "\t\t %s /* default_value */,\n"
2037 value_for_print (p->canonical_name, p->name),
2038 value_for_print (p->nick, "NULL"),
2039 value_for_print (p->blurb, "NULL"),
2040 value_for_print (p->minimum, "G_MININT64"),
2041 value_for_print (p->maximum, "G_MAXINT64"),
2042 value_for_print (p->default_value, "0"),
2044 } else if (strcmp (p->gtktype, "UINT64") == 0) {
2045 out_printf (out, "\tparam_spec = g_param_spec_uint64\n"
2046 "\t\t(\"%s\" /* name */,\n"
2047 "\t\t %s /* nick */,\n"
2048 "\t\t %s /* blurb */,\n"
2049 "\t\t %s /* minimum */,\n"
2050 "\t\t %s /* maximum */,\n"
2051 "\t\t %s /* default_value */,\n"
2053 value_for_print (p->canonical_name, p->name),
2054 value_for_print (p->nick, "NULL"),
2055 value_for_print (p->blurb, "NULL"),
2056 value_for_print (p->minimum, "0"),
2057 value_for_print (p->maximum, "G_MAXUINT64"),
2058 value_for_print (p->default_value, "0"),
2060 } else if (strcmp (p->gtktype, "UNICHAR") == 0) {
2061 out_printf (out, "\tparam_spec = g_param_spec_unichar\n"
2062 "\t\t(\"%s\" /* name */,\n"
2063 "\t\t %s /* nick */,\n"
2064 "\t\t %s /* blurb */,\n"
2065 "\t\t %s /* default_value */,\n"
2067 value_for_print (p->canonical_name, p->name),
2068 value_for_print (p->nick, "NULL"),
2069 value_for_print (p->blurb, "NULL"),
2070 value_for_print (p->default_value, "0"),
2072 } else if (strcmp (p->gtktype, "ENUM") == 0) {
2073 char *type = make_me_type (p->extra_gtktype,
2075 out_printf (out, "\tparam_spec = g_param_spec_enum\n"
2076 "\t\t(\"%s\" /* name */,\n"
2077 "\t\t %s /* nick */,\n"
2078 "\t\t %s /* blurb */,\n"
2079 "\t\t %s /* enum_type */,\n"
2080 "\t\t %s /* default_value */,\n"
2082 value_for_print (p->canonical_name, p->name),
2083 value_for_print (p->nick, "NULL"),
2084 value_for_print (p->blurb, "NULL"),
2086 value_for_print (p->default_value, "0"),
2089 } else if (strcmp (p->gtktype, "FLAGS") == 0) {
2090 char *type = make_me_type (p->extra_gtktype,
2092 out_printf (out, "\tparam_spec = g_param_spec_flags\n"
2093 "\t\t(\"%s\" /* name */,\n"
2094 "\t\t %s /* nick */,\n"
2095 "\t\t %s /* blurb */,\n"
2096 "\t\t %s /* flags_type */,\n"
2097 "\t\t %s /* default_value */,\n"
2099 value_for_print (p->canonical_name, p->name),
2100 value_for_print (p->nick, "NULL"),
2101 value_for_print (p->blurb, "NULL"),
2103 value_for_print (p->default_value, "0"),
2106 } else if (strcmp (p->gtktype, "FLOAT") == 0) {
2107 out_printf (out, "\tparam_spec = g_param_spec_float\n"
2108 "\t\t(\"%s\" /* name */,\n"
2109 "\t\t %s /* nick */,\n"
2110 "\t\t %s /* blurb */,\n"
2111 "\t\t %s /* minimum */,\n"
2112 "\t\t %s /* maximum */,\n"
2113 "\t\t %s /* default_value */,\n"
2115 value_for_print (p->canonical_name, p->name),
2116 value_for_print (p->nick, "NULL"),
2117 value_for_print (p->blurb, "NULL"),
2118 value_for_print (p->minimum, "-G_MAXFLOAT"),
2119 value_for_print (p->maximum, "G_MAXFLOAT"),
2120 value_for_print (p->default_value, "0.0"),
2122 } else if (strcmp (p->gtktype, "DOUBLE") == 0) {
2123 out_printf (out, "\tparam_spec = g_param_spec_double\n"
2124 "\t\t(\"%s\" /* name */,\n"
2125 "\t\t %s /* nick */,\n"
2126 "\t\t %s /* blurb */,\n"
2127 "\t\t %s /* minimum */,\n"
2128 "\t\t %s /* maximum */,\n"
2129 "\t\t %s /* default_value */,\n"
2131 value_for_print (p->canonical_name, p->name),
2132 value_for_print (p->nick, "NULL"),
2133 value_for_print (p->blurb, "NULL"),
2134 value_for_print (p->minimum, "-G_MAXDOUBLE"),
2135 value_for_print (p->maximum, "G_MAXDOUBLE"),
2136 value_for_print (p->default_value, "0.0"),
2138 } else if (strcmp (p->gtktype, "STRING") == 0) {
2139 out_printf (out, "\tparam_spec = g_param_spec_string\n"
2140 "\t\t(\"%s\" /* name */,\n"
2141 "\t\t %s /* nick */,\n"
2142 "\t\t %s /* blurb */,\n"
2143 "\t\t %s /* default_value */,\n"
2145 value_for_print (p->canonical_name, p->name),
2146 value_for_print (p->nick, "NULL"),
2147 value_for_print (p->blurb, "NULL"),
2148 value_for_print (p->default_value, "NULL"),
2150 } else if (strcmp (p->gtktype, "PARAM") == 0) {
2151 char *type = make_me_type (p->extra_gtktype,
2153 out_printf (out, "\tparam_spec = g_param_spec_param\n"
2154 "\t\t(\"%s\" /* name */,\n"
2155 "\t\t %s /* nick */,\n"
2156 "\t\t %s /* blurb */,\n"
2157 "\t\t %s /* param_type */,\n"
2159 value_for_print (p->canonical_name, p->name),
2160 value_for_print (p->nick, "NULL"),
2161 value_for_print (p->blurb, "NULL"),
2165 } else if (strcmp (p->gtktype, "BOXED") == 0) {
2166 char *type = make_me_type (p->extra_gtktype,
2168 out_printf (out, "\tparam_spec = g_param_spec_boxed\n"
2169 "\t\t(\"%s\" /* name */,\n"
2170 "\t\t %s /* nick */,\n"
2171 "\t\t %s /* blurb */,\n"
2172 "\t\t %s /* boxed_type */,\n"
2174 value_for_print (p->canonical_name, p->name),
2175 value_for_print (p->nick, "NULL"),
2176 value_for_print (p->blurb, "NULL"),
2180 } else if (strcmp (p->gtktype, "POINTER") == 0) {
2181 out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
2182 "\t\t(\"%s\" /* name */,\n"
2183 "\t\t %s /* nick */,\n"
2184 "\t\t %s /* blurb */,\n"
2186 value_for_print (p->canonical_name, p->name),
2187 value_for_print (p->nick, "NULL"),
2188 value_for_print (p->blurb, "NULL"),
2190 /* FIXME: VALUE_ARRAY */
2191 } else if (strcmp (p->gtktype, "CLOSURE") == 0) {
2192 out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
2193 "\t\t(\"%s\" /* name */,\n"
2194 "\t\t %s /* nick */,\n"
2195 "\t\t %s /* blurb */,\n"
2197 value_for_print (p->canonical_name, p->name),
2198 value_for_print (p->nick, "NULL"),
2199 value_for_print (p->blurb, "NULL"),
2201 } else if (strcmp (p->gtktype, "OBJECT") == 0) {
2202 char *type = make_me_type (p->extra_gtktype,
2204 out_printf (out, "\tparam_spec = g_param_spec_object\n"
2205 "\t\t(\"%s\" /* name */,\n"
2206 "\t\t %s /* nick */,\n"
2207 "\t\t %s /* blurb */,\n"
2208 "\t\t %s /* object_type */,\n"
2210 value_for_print (p->canonical_name, p->name),
2211 value_for_print (p->nick, "NULL"),
2212 value_for_print (p->blurb, "NULL"),
2217 error_printf (GOB_ERROR, p->line_no,
2218 "%s type is not supported by properties",
2222 s = g_strdup (p->name);
2224 out_printf (out, "\tg_object_class_install_property (g_object_class,\n"
2226 "\t\tparam_spec);\n", s);
2229 g_string_free (flags, TRUE);
2234 make_arguments(Class *c)
2237 if (get_properties > 0)
2238 out_printf(out, "\tg_object_class->get_property = ___object_get_property;\n");
2239 if (set_properties > 0)
2240 out_printf(out, "\tg_object_class->set_property = ___object_set_property;\n");
2241 out_printf (out, " {\n");
2242 for (li = c->nodes; li != NULL; li = li->next) {
2244 if ((n->type == PROPERTY_NODE && ! ((Property *) n)->override)
2245 || n->type == ARGUMENT_NODE) {
2246 out_printf(out, "\tGParamSpec *param_spec;\n\n");
2251 for (li = c->nodes; li != NULL; li = li->next) {
2253 if (n->type == PROPERTY_NODE)
2254 make_property ((Property *)n);
2255 else if (n->type == ARGUMENT_NODE)
2256 make_argument ((Argument *)n);
2258 out_printf(out, " }\n");
2262 print_initializer(Method *m, Variable *v)
2269 if(v->initializer == NULL)
2272 if(v->scope == PRIVATE_SCOPE)
2273 root = g_strconcat(((FuncArg *)m->args->data)->name,
2276 root = g_strdup(((FuncArg *)m->args->data)->name);
2278 if(v->initializer_line > 0)
2279 out_addline_infile(out, v->initializer_line);
2281 if (v->initializer_simple)
2282 out_printf(out, "\t%s->%s = %s;\n",
2283 root, v->id, v->initializer);
2284 else if (strcmp(v->id, "_glade_xml") == 0)
2285 /* This is OK, this v->initializer string is set internally
2286 and it will eat exactly one string! */
2287 out_printf(out,v->initializer, ((FuncArg *)m->args->data)->name);
2289 out_printf(out, "%s", v->initializer);
2291 if(v->initializer_line > 0)
2292 out_addline_outfile(out);
2298 print_glade_widget(Method *m, Variable *v)
2303 if(!v->glade_widget)
2306 if(v->scope == PRIVATE_SCOPE)
2307 root = g_strconcat(((FuncArg *)m->args->data)->name,
2310 root = g_strdup(((FuncArg *)m->args->data)->name);
2312 cast = get_type(v->vtype, FALSE);
2313 out_printf(out, "\t%s->%s = (%s)glade_xml_get_widget(%s->_glade_xml, \"%s\");\n",
2314 root, v->id, cast, root, v->id);
2320 print_destructor (Variable *v)
2324 if(v->destructor == NULL)
2327 if(v->scope == PRIVATE_SCOPE)
2328 root = "self->_priv";
2332 if(v->destructor_simple) {
2333 if(v->destructor_line > 0)
2334 out_addline_infile(out, v->destructor_line);
2337 out_printf(out, "\tif(%s->%s) { "
2338 "(reinterpret_cast<void (*)(void *)>(%s)) ((gpointer)%s->%s); "
2339 "%s->%s = NULL; }\n",
2340 root, v->id, v->destructor, root, v->id,
2343 out_printf(out, "\tif(%s->%s) { "
2344 "%s ((gpointer) %s->%s); "
2345 "%s->%s = NULL; }\n",
2346 root, v->id, v->destructor, root, v->id,
2350 if(v->destructor_line > 0)
2351 out_addline_outfile(out);
2353 out_printf(out, "#define %s (%s->%s)\n", v->id, root, v->id);
2354 out_printf(out, "#define VAR %s\n", v->id);
2355 out_printf(out, "\t{\n");
2356 if(v->destructor_line > 0)
2357 out_addline_infile(out, v->destructor_line);
2359 out_printf(out, "\t%s}\n", v->destructor);
2361 if(v->destructor_line > 0)
2362 out_addline_outfile(out);
2363 out_printf(out, "\tmemset(&(%s), 0, sizeof(%s));\n",
2365 out_printf(out, "#undef VAR\n");
2366 out_printf(out, "#undef %s\n", v->id);
2371 add_constructor (Class *c)
2373 out_printf(out, "\nstatic GObject *\n"
2374 "___constructor (GType type, guint n_construct_properties, GObjectConstructParam *construct_properties)\n"
2377 "#define __GOB_FUNCTION__ \"%s::constructor\"\n",
2380 out_printf(out, "\tGObject *obj_self;\n");
2381 out_printf(out, "\t%s *self;\n", typebase);
2383 out_printf(out, "\tobj_self = G_OBJECT_CLASS (parent_class)->constructor (type, n_construct_properties, construct_properties);\n");
2384 out_printf(out, "\tself = %s (obj_self);\n", macrobase);
2386 if (user_constructor->line_no > 0)
2387 out_addline_infile (out, user_constructor->line_no);
2388 out_printf (out, "\t%s_constructor (self);\n", funcbase);
2389 if (user_constructor->line_no > 0)
2390 out_addline_outfile (out);
2392 out_printf(out, "\treturn obj_self;\n");
2393 out_printf(out, "}\n"
2394 "#undef __GOB_FUNCTION__\n\n");
2398 print_unreftors (Class *c)
2401 for(li = ((Class *)class)->nodes;
2405 Variable *v = (Variable *)n;
2406 if (n->type == VARIABLE_NODE &&
2407 v->scope != CLASS_SCOPE &&
2408 v->destructor_unref)
2409 print_destructor (v);
2414 add_dispose (Class *c)
2416 out_printf(out, "\nstatic void\n"
2417 "___dispose (GObject *obj_self)\n"
2420 "#define __GOB_FUNCTION__ \"%s::dispose\"\n",
2423 if (unreftors > 0 || user_dispose_method != NULL) {
2424 out_printf (out, "\t%s *self%s = %s (obj_self);\n",
2426 ! no_gnu ? " G_GNUC_UNUSED" : "",
2430 if (dispose_handler != NULL) {
2431 if (unreftors > 0) {
2432 print_unreftors (c);
2435 /* so we get possible bad argument warning */
2436 if (dispose_handler->line_no > 0)
2437 out_addline_infile (out, dispose_handler->line_no);
2438 out_printf (out, "\t___%x_%s_dispose(obj_self);\n",
2439 (guint)dispose_handler->unique_id, funcbase);
2440 if (dispose_handler->line_no > 0)
2441 out_addline_outfile (out);
2443 if (user_dispose_method != NULL) {
2444 if (user_dispose_method->line_no > 0)
2445 out_addline_infile (out, user_dispose_method->line_no);
2446 out_printf (out, "\t%s_dispose (self);\n", funcbase);
2447 if (user_dispose_method->line_no > 0)
2448 out_addline_outfile (out);
2451 if (unreftors > 0) {
2452 print_unreftors (c);
2456 "\tif (G_OBJECT_CLASS (parent_class)->dispose) \\\n"
2457 "\t\t(* G_OBJECT_CLASS (parent_class)->dispose) (obj_self);\n");
2460 out_printf(out, "}\n"
2461 "#undef __GOB_FUNCTION__\n\n");
2465 print_destructors (Class *c)
2468 for (li = ((Class *)class)->nodes;
2472 Variable *v = (Variable *)n;
2473 if (n->type == VARIABLE_NODE &&
2474 v->scope != CLASS_SCOPE &&
2475 ! v->destructor_unref)
2476 print_destructor (v);
2481 add_finalize (Class *c)
2485 "___finalize(GObject *obj_self)\n"
2488 "#define __GOB_FUNCTION__ \"%s::finalize\"\n",
2493 user_finalize_method != NULL) {
2494 const char *unused = "";
2496 unused = " G_GNUC_UNUSED";
2497 out_printf(out, "\t%s *self%s = %s (obj_self);\n",
2498 typebase, unused, macrobase);
2501 const char *unused = "";
2503 unused = " G_GNUC_UNUSED";
2504 out_printf(out, "\tgpointer priv%s = self->_priv;\n",
2508 if(finalize_handler) {
2509 if (destructors > 0) {
2510 print_destructors (c);
2513 /* so we get possible bad argument warning */
2514 if(finalize_handler->line_no > 0)
2515 out_addline_infile(out, finalize_handler->line_no);
2516 out_printf(out, "\t___%x_%s_finalize(obj_self);\n",
2517 (guint)finalize_handler->unique_id, funcbase);
2518 if(finalize_handler->line_no > 0)
2519 out_addline_outfile(out);
2521 if (user_finalize_method != NULL) {
2522 if (user_finalize_method->line_no > 0)
2523 out_addline_infile (out, user_finalize_method->line_no);
2524 out_printf (out, "\t%s_finalize (self);\n", funcbase);
2525 if (user_finalize_method->line_no > 0)
2526 out_addline_outfile (out);
2529 if (destructors > 0) {
2530 print_destructors (c);
2534 "\tif(G_OBJECT_CLASS(parent_class)->finalize) \\\n"
2535 "\t\t(* G_OBJECT_CLASS(parent_class)->finalize)(obj_self);\n");
2538 out_printf(out, "}\n"
2539 "#undef __GOB_FUNCTION__\n\n");
2543 make_bonobo_object_epv (Class *c, const char *classname)
2546 gboolean added_line = FALSE;
2548 for (li = c->nodes; li != NULL; li = li->next) {
2550 Method *m = (Method *)n;
2551 if(n->type != METHOD_NODE ||
2552 m->method == OVERRIDE_METHOD)
2555 if (m->bonobo_object_func) {
2556 if(m->line_no > 0) {
2557 out_addline_infile(out, m->line_no);
2559 } else if (m->line_no == 0 &&
2561 out_addline_outfile(out);
2564 out_printf (out, "\t%s->_epv.%s = self_%s;\n",
2565 classname, m->id, m->id);
2569 out_addline_outfile(out);
2572 static void add_class_private(Class *c, Method *m)
2574 const char *dynamic = c->dynamic ? "_DYNAMIC" : "";
2579 out_printf(out, "\n#if !defined(G_DEFINE%s_TYPE_EXTENDED)"
2580 " || !defined(G_ADD_PRIVATE%s)\n"
2581 "\tg_type_class_add_private(%s, sizeof(%sPrivate));\n"
2584 ((FuncArg *)m->args->data)->name, typebase);
2587 static void get_instance_private(Class *c, Method *m)
2589 const char *self = ((FuncArg *)m->args->data)->name;
2590 const char *dynamic = c->dynamic ? "_DYNAMIC" : "";
2593 if (always_private_struct) {
2594 out_printf(out, "\t%s->_priv = NULL;\n", self);
2600 out_printf(out, "\t%s->_priv = (%sPrivate *)\n"
2601 "#if defined(G_DEFINE%s_TYPE_EXTENDED)"
2602 " && defined(G_ADD_PRIVATE%s)\n"
2603 "\t\t%s_get_instance_private(%s);\n"
2605 "\t\tG_TYPE_INSTANCE_GET_PRIVATE\n"
2608 "\t\t\t, %sPrivate\n"
2614 self, macrotype, typebase);
2620 const char *unused = "";
2624 unused = " G_GNUC_UNUSED";
2626 for(li=c->nodes;li;li=g_list_next(li)) {
2630 if(n->type != METHOD_NODE)
2633 if(m->method == INIT_METHOD) {
2635 out_addline_infile(out, m->line_no);
2636 print_method(out, "static ", "\n", "", " ", "", "\n",
2637 m, FALSE, FALSE, FALSE, TRUE, TRUE,
2639 out_printf(out, "{\n");
2641 out_addline_outfile(out);
2643 "#define __GOB_FUNCTION__ \"%s::init\"\n",
2646 get_instance_private(c, m);
2648 if(initializers > 0) {
2650 for(li = ((Class *)class)->nodes;
2654 Variable *v = (Variable *)n;
2655 if(n->type != VARIABLE_NODE ||
2656 v->scope == CLASS_SCOPE)
2658 print_initializer(m, v);
2661 if(glade_widgets > 0) {
2663 for(li = ((Class *)class)->nodes;
2667 Variable *v = (Variable *)n;
2668 if(n->type != VARIABLE_NODE ||
2669 v->scope == CLASS_SCOPE)
2671 print_glade_widget(m, v);
2674 } else if(m->method == CLASS_INIT_METHOD) {
2675 gboolean did_base_obj = FALSE;
2678 out_addline_infile(out, m->line_no);
2679 print_method(out, "static ", "\n", "", " ", "", "\n",
2680 m, FALSE, FALSE, FALSE, TRUE, TRUE,
2682 out_printf(out, "{\n");
2684 out_addline_outfile(out);
2686 "#define __GOB_FUNCTION__ \"%s::class_init\"\n",
2688 if (set_properties > 0 ||
2689 get_properties > 0 ||
2696 "g_object_class%s = "
2697 "(GObjectClass*) %s;\n",
2699 ((FuncArg *)m->args->data)->name);
2700 did_base_obj = TRUE;
2705 ((FuncArg *)m->args->data)->name,
2708 add_class_private(c, m);
2710 if (initializers > 0) {
2712 for(li = ((Class *)class)->nodes;
2716 Variable *v = (Variable *)n;
2717 if(n->type == VARIABLE_NODE &&
2718 v->scope == CLASS_SCOPE)
2719 print_initializer(m, v);
2723 out_printf(out, "\n\tparent_class = ");
2725 out_printf(out, "(%sClass *)", ptypebase);
2726 out_printf(out, "g_type_class_ref (%s);\n",
2732 set_def_handlers(c, ((FuncArg *)m->args->data)->name);
2734 /* if there are no handlers for these things, we
2735 * need to set them up here */
2736 if(need_constructor)
2737 out_printf(out, "\tg_object_class->constructor "
2738 "= ___constructor;\n");
2739 if(need_dispose && !dispose_handler)
2740 out_printf(out, "\tg_object_class->dispose "
2742 if(need_finalize && !finalize_handler)
2743 out_printf(out, "\tg_object_class->finalize = "
2746 if(get_properties > 0 || set_properties > 0)
2749 if (c->bonobo_object_class != NULL) {
2750 make_bonobo_object_epv (c, ((FuncArg *)m->args->data)->name);
2756 out_printf(out, " {\n");
2757 out_addline_infile(out, m->ccode_line);
2758 out_printf(out, "%s\n", m->cbuf);
2759 out_addline_outfile(out);
2760 out_printf(out, " }\n");
2762 out_printf(out, "}\n"
2763 "#undef __GOB_FUNCTION__\n");
2768 add_argument (Argument *a, gboolean is_set)
2772 char *the_type_lower;
2777 line_no = a->set_line;
2780 line_no = a->get_line;
2784 s = g_strdup(a->name);
2786 out_printf(out, "\tcase PROP_%s:\n\t{", s);
2788 the_type_lower = g_strdup (a->gtktype);
2789 gob_strdown (the_type_lower);
2791 /* HACK because there is no g_value_set/get for unichar */
2792 if (strcmp (the_type_lower, "unichar") == 0) {
2793 g_free (the_type_lower);
2794 the_type_lower = g_strdup ("uint");
2799 const char *unused = "";
2801 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
2802 unused = " G_GNUC_UNUSED";
2805 if (a->atype != NULL &&
2806 /* gcc -Wbad-function-cast is wanking stupid, moronic
2807 and otherwise evil so we should just use a (gint)
2808 or (guint) cast, not the specific type cast */
2810 (strcmp (a->gtktype, "ENUM") != 0 &&
2811 strcmp (a->gtktype, "FLAGS") != 0)))
2812 cast = get_type (a->atype, TRUE);
2814 cast = g_strdup (get_cast (a->gtktype, FALSE));
2816 out_printf (out, "\t%s ARG%s = (%s) g_value_get_%s (VAL);\n",
2817 cast, unused, cast, the_type_lower);
2820 } else if ( ! is_set) {
2823 if (a->atype != NULL)
2824 cast = get_type (a->atype, TRUE);
2826 cast = g_strdup (get_cast (a->gtktype, FALSE));
2827 out_printf (out, "\t%s ARG;\n"
2828 "\tmemset (&ARG, 0, sizeof (%s));\n",
2834 out_printf(out, "\t\t{\n");
2836 out_addline_infile (out, line_no);
2837 out_printf (out, "%s\n", cbuf);
2839 out_addline_outfile (out);
2840 out_printf (out, "\t\t}\n");
2842 if (strcmp (a->gtktype, "OBJECT") == 0)
2843 out_printf (out, "\t\tg_value_set_%s (VAL, G_OBJECT (ARG));\n",
2846 out_printf (out, "\t\t"
2847 "g_value_set_%s (VAL, ARG);\n",
2850 g_free (the_type_lower);
2853 (no_gnu || for_cpp /* g++ has a cow with G_GNUC_UNUSED */)) {
2854 out_printf (out, "\t\tif (&ARG) break;\n");
2857 out_printf (out, "\t\tbreak;\n");
2859 out_printf (out, "\t}\n");
2863 add_property (Property *p, gboolean is_set)
2866 char *the_type_lower;
2872 line_no = p->set_line;
2875 line_no = p->get_line;
2880 name_upper = g_strdup (p->name);
2881 gob_strup (name_upper);
2882 the_type_lower = g_strdup (p->gtktype);
2883 gob_strdown (the_type_lower);
2885 out_printf (out, "\tcase PROP_%s:\n", name_upper);
2887 out_printf(out, "\t\t{\n");
2889 out_addline_infile (out, line_no);
2890 out_printf (out, "%s\n", cbuf);
2892 out_addline_outfile (out);
2893 out_printf (out, "\t\t}\n");
2895 g_free (name_upper);
2896 g_free (the_type_lower);
2898 out_printf (out, "\t\tbreak;\n");
2902 add_getset_arg(Class *c, gboolean is_set)
2905 const char *unused = "";
2906 const char *hack_unused = "";
2908 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
2909 unused = " G_GNUC_UNUSED";
2911 hack_unused = "if (&VAL || &pspec) break;\n\t\t";
2914 out_printf(out, "\nstatic void\n"
2915 "___object_%s_property (GObject *object,\n"
2916 "\tguint property_id,\n"
2917 "\t%sGValue *VAL%s,\n"
2918 "\tGParamSpec *pspec%s)\n"
2919 "#define __GOB_FUNCTION__ \"%s::%s_property\"\n"
2922 "\tself = %s (object);\n\n"
2923 "\tswitch (property_id) {\n",
2924 is_set ? "set" : "get",
2925 is_set ? "const " : "",
2929 is_set ? "set" : "get",
2934 for (li = c->nodes; li != NULL; li = li->next) {
2936 if (n->type == PROPERTY_NODE)
2937 add_property ((Property *)n, is_set);
2938 else if (n->type == ARGUMENT_NODE)
2939 add_argument ((Argument *)n, is_set);
2941 out_printf (out, "\tdefault:\n"
2942 "/* Apparently in g++ this is needed, glib is b0rk */\n"
2943 "#ifndef __PRETTY_FUNCTION__\n"
2944 "# undef G_STRLOC\n"
2945 "# define G_STRLOC __FILE__ \":\" G_STRINGIFY (__LINE__)\n"
2947 "\t\tG_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);\n"
2948 "\t\t%sbreak;\n\t}\n"
2950 "#undef __GOB_FUNCTION__\n", hack_unused);
2954 print_checks (Method *m, FuncArg *fa)
2958 gboolean checked_null = FALSE;
2959 is_void = (strcmp(m->mtype->name, "void")==0 &&
2960 m->mtype->pointer == NULL);
2962 for(li = fa->checks; li != NULL; li = li->next) {
2963 Check *ch = li->data;
2965 /* point to the method prot in .gob for failed checks */
2967 out_addline_infile(out, m->line_no);
2969 out_printf(out, "\tg_return_if_fail (");
2971 out_printf(out, "\tg_return_val_if_fail (");
2972 switch(ch->chtype) {
2974 out_printf(out, "%s != NULL", fa->name);
2975 checked_null = TRUE;
2978 s = make_pre_macro(fa->atype->name, "IS");
2980 out_printf(out, "%s (%s)", s, fa->name);
2982 /* if not check null, null may be valid */
2983 out_printf(out, "!(%s) || %s (%s)", fa->name,
2988 out_printf(out, "%s < %s", fa->name, ch->number);
2991 out_printf(out, "%s > %s", fa->name, ch->number);
2994 out_printf(out, "%s <= %s", fa->name, ch->number);
2997 out_printf(out, "%s >= %s", fa->name, ch->number);
3000 out_printf(out, "%s == %s", fa->name, ch->number);
3003 out_printf(out, "%s != %s", fa->name, ch->number);
3007 out_printf(out, ");\n");
3009 out_printf(out, ", (");
3010 print_type(out, m->mtype, TRUE);
3011 out_printf(out, ")%s);\n",
3012 m->onerror?m->onerror:"0");
3018 print_preconditions(Method *m)
3022 for(li=m->args;li;li=g_list_next(li)) {
3023 FuncArg *fa = li->data;
3025 print_checks(m, fa);
3028 out_addline_outfile(out);
3032 print_method_body (Method *m, gboolean pre, gboolean unused_self)
3034 out_printf(out, "{\n");
3036 out_addline_outfile(out);
3037 out_printf(out, "#define __GOB_FUNCTION__ \"%s::%s\"\n",
3038 ((Class *)class)->otype,
3041 print_preconditions(m);
3045 (no_gnu || for_cpp) &&
3047 ((FuncArg *)(m->args->data))->name != NULL &&
3048 strcmp (((FuncArg *)(m->args->data))->name, "self") == 0) {
3049 out_printf (out, "\tif (&self) { ; }\n");
3052 /* Note: the trailing }'s are on one line, this is so
3053 that we get the no return warning correctly and point to
3054 the correct line in the .gob file, yes this is slightly
3055 ugly in the .c file, but that is not supposed to be
3056 human readable anyway. */
3058 out_printf(out, "{\n");
3060 out_addline_infile(out, m->ccode_line);
3061 out_printf(out, "\t%s}", m->cbuf);
3064 /* Note, there is no \n between the last } and this } so that
3065 * errors/warnings reported on the end of the body get pointed to the
3066 * right line in the .gob source */
3067 out_printf(out, "}\n");
3070 out_addline_outfile(out);
3071 out_printf(out, "#undef __GOB_FUNCTION__\n");
3075 put_signal_args (Method *m)
3081 if (m->args->next == NULL)
3084 for (ali = m->gtktypes->next, li = m->args->next, i = 1;
3085 li != NULL && ali != NULL;
3086 li = li->next, ali = ali->next, i++) {
3087 FuncArg *fa = li->data;
3088 char *str = ali->data;
3089 char *cast = g_strdup (get_cast (str, FALSE));
3090 /* FIXME: This code is so fucking ugly it hurts */
3091 gboolean do_static =
3092 (strcmp (str, "STRING") == 0 ||
3093 strcmp (str, "BOXED") == 0 ||
3094 strncmp (str, "BOXED_", 6) == 0);
3099 cast = get_type (fa->atype, TRUE);
3101 /* we should have already proved before that
3102 the we know all the types */
3103 g_assert (cast != NULL);
3105 if (strncmp (str, "BOXED_", 6) == 0)
3106 t = g_strdup (&(str[6]));
3108 t = g_strconcat ("G_TYPE_", str, NULL);
3111 "\t___param_values[%d].g_type = 0;\n"
3112 "\tg_value_init (&___param_values[%d], %s);\n",
3116 if (strcmp (str, "UNICHAR") == 0)
3117 /* hack because glib is braindamaged */
3118 set_func = g_strdup ("g_value_set_uint");
3119 else if (strncmp (str, "BOXED_", 6) == 0)
3120 set_func = g_strdup ("g_value_set_static_boxed");
3122 set_func = g_strdup_printf ("g_value_set%s_%s",
3123 do_static ? "_static" : "",
3125 gob_strdown (set_func);
3127 out_printf (out, "\t%s (&___param_values[%d], (%s) %s);\n\n",
3128 set_func, i, cast, fa->name);
3136 clear_signal_args (Method *m)
3141 out_printf (out, "\n\tg_value_unset (&___param_values[0]);\n");
3143 if (m->args->next == NULL)
3146 for (li = m->args->next, i = 1;
3148 li = li->next, i++) {
3150 "\tg_value_unset (&___param_values[%d]);\n", i);
3155 get_arg_names_for_macro (Method *m)
3159 GString *gs = g_string_new(NULL);
3161 for(li=m->args;li;li=g_list_next(li)) {
3162 FuncArg *arg = li->data;
3163 g_string_sprintfa (gs, "%s___%s", sep, arg->name);
3166 return g_string_free (gs, FALSE);
3169 static gboolean method_is_void(Method *m)
3171 return !strcmp(m->mtype->name, "void") && !m->mtype->pointer;
3174 static const char *method_err_retval(Method *m)
3176 if (method_is_void(m))
3184 put_interface_parent_handler(Method *m)
3186 const char *errval = method_err_retval(m);
3187 char *name = replace_sep(m->interface, '_');
3188 char *args = get_arg_names_for_macro(m);
3190 out_printf(out, "#define PARENT_HANDLER(%s) (%s_parent_iface \\\n"
3191 "\t? %s_parent_iface->%s(%s) \\\n"
3192 "\t: %s)\n", args, name, name, m->id, args, errval);
3199 put_method(Method *m)
3201 char *s, *args, *doc;
3203 is_void = (strcmp(m->mtype->name, "void")==0 &&
3204 m->mtype->pointer == NULL);
3205 out_printf(out, "\n");
3206 if(m->method != OVERRIDE_METHOD) {
3207 doc = get_gtk_doc(m->id);
3209 out_printf(out, "%s", doc);
3215 case REGULAR_METHOD:
3217 out_addline_infile(out, m->line_no);
3218 if(m->scope == PRIVATE_SCOPE)
3219 print_method(out, "static ", "\n", "", " ", "", "\n",
3220 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3221 else /* PUBLIC, PROTECTED */
3222 print_method(out, "", "\n", "", " ", "", "\n",
3223 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3226 out_addline_outfile(out);
3227 put_interface_parent_handler(m);
3230 print_method_body(m, TRUE, TRUE);
3233 out_printf(out, "#undef PARENT_HANDLER\n");
3236 /* the outfile line was added above */
3238 case SIGNAL_FIRST_METHOD:
3239 case SIGNAL_LAST_METHOD:
3241 out_addline_infile(out, m->line_no);
3242 if(m->scope == PRIVATE_SCOPE)
3243 print_method(out, "static ", "\n", "", " ", "", "\n",
3244 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3245 else /* PUBLIC, PROTECTED */
3246 print_method(out, "", "\n", "", " ", "", "\n",
3247 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3248 out_printf (out, "{\n");
3250 out_addline_outfile (out);
3253 "\tGValue ___param_values[%d];\n"
3254 "\tGValue ___return_val;\n\n"
3255 "memset (&___return_val, 0, "
3256 "sizeof (___return_val));\n"
3257 "memset (&___param_values, 0, "
3258 "sizeof (___param_values));\n\n",
3259 g_list_length (m->args));
3261 print_preconditions (m);
3264 "\n\t___param_values[0].g_type = 0;\n"
3265 "\tg_value_init (&___param_values[0], G_TYPE_FROM_INSTANCE (%s));\n"
3266 "\tg_value_set_instance (&___param_values[0], (gpointer) %s);\n\n",
3267 ((FuncArg *)m->args->data)->name,
3268 ((FuncArg *)m->args->data)->name);
3270 put_signal_args (m);
3272 if (strcmp (m->gtktypes->data, "NONE") != 0) {
3273 const char *defret = NULL;
3275 out_printf (out, "\tg_value_init (&___return_val, G_TYPE_%s);\n",
3276 (char *)m->gtktypes->data);
3278 if (m->defreturn != NULL)
3279 defret = m->defreturn;
3280 else if (m->onerror != NULL)
3281 defret = m->onerror;
3283 if (defret != NULL) {
3285 /* FIXME: This code is so fucking ugly it hurts */
3286 gboolean do_static =
3287 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
3288 strcmp ((char *)m->gtktypes->data, "BOXED") == 0);
3289 char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
3291 cast = get_type (m->mtype, TRUE);
3293 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
3294 /* hack because glib is braindamaged */
3295 set_func = g_strdup ("g_value_set_uint");
3297 set_func = g_strdup_printf ("g_value_set%s_%s",
3298 do_static ? "_static" : "",
3299 (char *)m->gtktypes->data);
3300 gob_strdown (set_func);
3302 out_printf (out, "\t%s (&___return_val, (%s) (%s));\n",
3303 set_func, cast, defret);
3308 out_printf (out, "\n");
3311 s = g_strdup (m->id);
3314 out_printf(out, "\tg_signal_emitv (___param_values,\n"
3315 "\t\tobject_signals[%s_SIGNAL],\n"
3316 "\t\t0 /* detail */,\n"
3317 "\t\t&___return_val);\n", s);
3321 clear_signal_args (m);
3323 if (strcmp (m->gtktypes->data, "NONE") != 0) {
3324 char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
3326 /* Hack because glib is very very braindead */
3328 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
3329 strcmp ((char *)m->gtktypes->data, "BOXED") == 0 ||
3330 strcmp ((char *)m->gtktypes->data, "OBJECT") == 0 ||
3331 strcmp ((char *)m->gtktypes->data, "PARAM") == 0);
3333 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
3334 /* hack because glib is braindamaged */
3335 getfunc = g_strdup ("g_value_get_uint");
3337 getfunc = g_strdup_printf ("g_value_%s_%s",
3338 do_dup ? "dup" : "get",
3339 (char *)m->gtktypes->data);
3340 gob_strdown (getfunc);
3343 cast = get_type (m->mtype, TRUE);
3348 print_type (out, m->mtype, TRUE);
3350 " ___ret = (%s) %s (&___return_val);\n"
3351 "\t\tg_value_unset (&___return_val);\n"
3352 "\t\treturn ___ret;\n"
3359 out_printf(out, "}\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 VIRTUAL_METHOD:
3372 out_addline_infile(out, m->line_no);
3373 if(m->scope==PRIVATE_SCOPE)
3374 print_method(out, "static ", "\n", "", " ", "", "\n",
3375 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3376 else /* PUBLIC, PROTECTED */
3377 print_method(out, "", "\n", "", " ", "", "\n",
3378 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3379 out_printf(out, "{\n");
3380 out_addline_outfile(out);
3381 out_printf(out, "\t%sClass *klass;\n", typebase);
3382 print_preconditions(m);
3383 out_printf(out, "\tklass = %s_GET_CLASS(%s);\n\n"
3384 "\tif(klass->%s)\n",
3385 macrobase, ((FuncArg *)m->args->data)->name,
3387 if(strcmp(m->mtype->name, "void") == 0 &&
3388 m->mtype->pointer == NULL) {
3390 out_printf(out, "\t\t(*klass->%s)(%s",
3392 ((FuncArg *)m->args->data)->name);
3393 for(li=m->args->next;li;li=g_list_next(li)) {
3394 FuncArg *fa = li->data;
3395 out_printf(out, ",%s", fa->name);
3397 out_printf(out, ");\n}\n");
3400 out_printf(out, "\t\treturn (*klass->%s)(%s",
3402 ((FuncArg *)m->args->data)->name);
3403 for(li=m->args->next;li;li=g_list_next(li)) {
3404 FuncArg *fa = li->data;
3405 out_printf(out, ",%s", fa->name);
3407 out_printf(out, ");\n"
3410 print_type(out, m->mtype, TRUE);
3412 out_printf(out, ")(%s);\n}\n", m->defreturn);
3414 out_printf(out, ")(%s);\n}\n", m->onerror);
3416 out_printf(out, ")(0);\n}\n");
3422 out_addline_infile(out, m->line_no);
3423 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
3424 m, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE);
3425 print_method_body(m, FALSE, TRUE);
3426 /* the outfile line was added above */
3428 case OVERRIDE_METHOD:
3432 out_addline_infile(out, m->line_no);
3433 s = g_strdup_printf("\n___%x_", (guint)m->unique_id);
3434 print_method(out, "static ", s, "", " ", "", "\n",
3435 m, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE);
3437 out_addline_outfile(out);
3438 s = replace_sep(m->otype, '_');
3440 args = get_arg_names_for_macro(m);
3442 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
3443 "\t{ if(%s_CLASS(parent_class)->%s) \\\n"
3444 "\t\t(* %s_CLASS(parent_class)->%s)(%s); }\n",
3445 args, s, m->id, s, m->id, args);
3447 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
3448 "\t((%s_CLASS(parent_class)->%s)? \\\n"
3449 "\t\t(* %s_CLASS(parent_class)->%s)(%s): \\\n"
3451 args, s, m->id, s, m->id, args);
3452 out_printf(out, "(");
3453 print_type(out, m->mtype, TRUE);
3454 out_printf(out, ")%s))\n",
3455 m->onerror?m->onerror:"0");
3459 print_method_body(m, TRUE, TRUE);
3460 /* the outfile line was added above */
3461 out_printf(out, "#undef PARENT_HANDLER\n");
3463 case CONSTRUCTOR_METHOD:
3464 case DISPOSE_METHOD:
3465 case FINALIZE_METHOD:
3467 out_addline_infile(out, m->line_no);
3468 print_method(out, "static ", "\n", "", " ", "", "\n",
3469 m, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE);
3470 print_method_body(m, TRUE, TRUE);
3471 /* the outfile line was added above */
3480 char *outfile, *outfileh, *outfileph;
3482 outfilebase = g_strconcat (fullfilebase, for_cpp ? ".cc" : ".c", NULL);
3483 outfile = g_strconcat(outfilebase, no_touch ? "#gob#" : "", NULL);
3485 outfilehbase = g_strconcat (fullfilebase, ".h", NULL);
3486 outfileh = g_strconcat(outfilehbase, no_touch_headers ? "#gob#" : "", NULL);
3488 if ((privates > 0 || protecteds > 0 ||
3489 private_header == PRIVATE_HEADER_ALWAYS) &&
3490 private_header != PRIVATE_HEADER_NEVER) {
3491 char sep[2] = {0,0};
3494 outfilephbase = g_strconcat (fullfilebase, sep, "private.h", NULL);
3495 outfileph = g_strconcat (outfilephbase, no_touch ? "#gob#" : "", NULL);
3497 outfilephbase = NULL;
3503 out = fopen (outfile, "w");
3505 error_printf (GOB_ERROR, 0,
3506 "Cannot open outfile: %s", outfile);
3508 outh = fopen (outfileh, "w");
3510 error_printf (GOB_ERROR, 0,
3511 "Cannot open outfile: %s", outfileh);
3513 if (outfileph != NULL) {
3514 outph = fopen (outfileph, "w");
3515 if (outph == NULL) {
3516 error_printf (GOB_ERROR, 0,
3517 "Cannot open outfile: %s",
3525 put_argument_nongnu_wrappers (Class *c)
3529 if (get_properties < 0 && set_properties < 0)
3532 for (li = c->nodes; li != NULL; li = li->next) {
3534 const char *name, *gtktype;
3540 if (n->type == ARGUMENT_NODE) {
3541 Argument *a = (Argument *)n;
3543 gtktype = a->gtktype;
3545 get = a->get != NULL;
3546 set = a->set != NULL;
3547 } else if (n->type == PROPERTY_NODE) {
3548 Property *p = (Property *)n;
3550 gtktype = p->gtktype;
3552 get = p->get != NULL;
3553 set = p->set != NULL;
3558 aname = g_strdup (name);
3562 cast = get_type (atype, TRUE);
3564 cast = g_strdup (get_cast (gtktype, TRUE));
3568 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3569 "\"%s\",(%s)(arg)\n",
3570 macrobase, aname, name, cast);
3572 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3573 "\"%s\",(%s*)(arg)\n",
3574 macrobase, aname, name, cast);
3577 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3579 macrobase, aname, name);
3581 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3583 macrobase, aname, name);
3591 put_argument_gnu_wrappers(Class *c)
3595 if(get_properties < 0 && set_properties < 0)
3598 for (li = c->nodes; li != NULL; li = li->next) {
3600 const char *name, *gtktype;
3606 if (n->type == ARGUMENT_NODE) {
3607 Argument *a = (Argument *)n;
3609 gtktype = a->gtktype;
3611 get = a->get != NULL;
3612 set = a->set != NULL;
3613 } else if (n->type == PROPERTY_NODE) {
3614 Property *p = (Property *)n;
3616 gtktype = p->gtktype;
3618 get = p->get != NULL;
3619 set = p->set != NULL;
3624 aname = g_strdup (name);
3628 cast = get_type (atype, TRUE);
3630 cast = g_strdup (get_cast (gtktype, TRUE));
3634 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3635 "\"%s\", __extension__ ({%sz = (arg); z;})\n",
3636 macrobase, aname, name, cast);
3638 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3639 "\"%s\", __extension__ ({%s*z = (arg); z;})\n",
3640 macrobase, aname, name, cast);
3643 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3645 macrobase, aname, name);
3647 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3649 macrobase, aname, name);
3657 print_ccode_block(CCode *cc)
3660 switch(cc->cctype) {
3662 /* HT code is printed exactly like normal header
3663 code but is printed before */
3666 out_printf(fp, "\n");
3669 /* AT code is printed exactly like normal 'all'
3670 code but is printed before */
3673 out_printf(outph, "\n");
3674 out_printf(outph, "%s\n", cc->cbuf);
3675 out_addline_infile(outph, cc->line_no);
3676 out_addline_outfile(outph);
3678 out_printf(outh, "\n");
3679 out_printf(outh, "%s\n", cc->cbuf);
3681 out_printf(fp, "\n");
3682 out_addline_infile(fp, cc->line_no);
3688 out_printf(fp, "\n");
3689 out_addline_infile(fp, cc->line_no);
3696 out_printf(fp, "\n");
3697 out_addline_infile(fp, cc->line_no);
3700 out_printf(fp, "%s\n", cc->cbuf);
3701 if(cc->cctype == C_CCODE ||
3702 cc->cctype == AD_CCODE ||
3703 cc->cctype == A_CCODE ||
3704 cc->cctype == AT_CCODE ||
3705 cc->cctype == PH_CCODE)
3706 out_addline_outfile(fp);
3710 print_class_block(Class *c)
3714 gboolean printed_private = FALSE;
3718 out_printf(outph ? outph : outh, "#include <gtk/gtk.h>\n");
3719 out_printf(outph ? outph : outh, "#include <glade/glade-xml.h>\n\n");
3723 out_printf(out, "/* utility types we may need */\n");
3724 if(special_array[SPECIAL_2POINTER])
3725 out_printf(out, "typedef struct { "
3726 "gpointer a; gpointer b; "
3727 "} ___twopointertype;\n");
3728 if(special_array[SPECIAL_3POINTER])
3729 out_printf(out, "typedef struct { "
3730 "gpointer a; gpointer b; "
3732 "} ___threepointertype;\n");
3733 if(special_array[SPECIAL_INT_POINTER])
3734 out_printf(out, "typedef struct { "
3735 "gint a; gpointer b; "
3736 "} ___intpointertype;\n");
3737 out_printf(out, "\n");
3740 out_printf(outh, "\n/*\n"
3741 " * Type checking and casting macros\n"
3743 out_printf(outh, "#define %s\t"
3744 "(%s_get_type())\n",
3745 macrotype, funcbase);
3746 out_printf(outh, "#define %s(obj)\t"
3747 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s)\n",
3748 macrobase, funcbase, typebase);
3749 out_printf(outh, "#define %s_CONST(obj)\t"
3750 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s const)\n",
3751 macrobase, funcbase, typebase);
3752 out_printf(outh, "#define %s_CLASS(klass)\t"
3753 "G_TYPE_CHECK_CLASS_CAST((klass), %s_get_type(), %sClass)\n",
3754 macrobase, funcbase, typebase);
3755 out_printf(outh, "#define %s(obj)\t"
3756 "G_TYPE_CHECK_INSTANCE_TYPE((obj), %s_get_type ())\n\n",
3759 "#define %s_GET_CLASS(obj)\t"
3760 "G_TYPE_INSTANCE_GET_CLASS((obj), %s_get_type(), %sClass)\n",
3761 macrobase, funcbase, typebase);
3763 if ( ! no_self_alias) {
3764 out_printf(out, "/* self casting macros */\n");
3765 out_printf(out, "#define SELF(x) %s(x)\n", macrobase);
3766 out_printf(out, "#define SELF_CONST(x) %s_CONST(x)\n", macrobase);
3767 out_printf(out, "#define IS_SELF(x) %s(x)\n", macrois);
3768 out_printf(out, "#define TYPE_SELF %s\n", macrotype);
3769 out_printf(out, "#define SELF_CLASS(x) %s_CLASS(x)\n\n",
3771 out_printf(out, "#define SELF_GET_CLASS(x) %s_GET_CLASS(x)\n\n",
3774 out_printf(out, "/* self typedefs */\n");
3775 out_printf(out, "typedef %s Self;\n", typebase);
3776 out_printf(out, "typedef %sClass SelfClass;\n\n", typebase);
3780 always_private_struct) {
3781 out_printf (outh, "\n/* Private structure type */\n");
3782 out_printf (outh, "typedef struct _%sPrivate %sPrivate;\n",
3783 typebase, typebase);
3785 out_printf (outh, "/* There are no privates, this "
3786 "structure is thus never defined */\n");
3789 out_printf (outh, "\n/*\n"
3790 " * Main object structure\n"
3792 s = replace_sep (c->otype, '_');
3794 out_printf (outh, "#ifndef __TYPEDEF_%s__\n"
3795 "#define __TYPEDEF_%s__\n", s, s);
3797 out_printf (outh, "typedef struct _%s %s;\n"
3798 "#endif\n", typebase, typebase);
3799 out_printf (outh, "struct _%s {\n\t%s __parent__;\n",
3800 typebase, ptypebase);
3801 for (li = c->nodes; li; li=li->next) {
3802 static gboolean printed_public = FALSE;
3804 Variable *v = (Variable *)n;
3805 if(n->type == VARIABLE_NODE &&
3806 v->scope == PUBLIC_SCOPE) {
3807 if( ! printed_public) {
3808 out_printf(outh, "\t/*< public >*/\n");
3809 printed_public = TRUE;
3811 put_variable((Variable *)n, outh);
3814 /* put protecteds always AFTER publics */
3815 for (li = c->nodes; li != NULL; li = li->next) {
3817 Variable *v = (Variable *)n;
3818 if (n->type == VARIABLE_NODE &&
3819 v->scope == PROTECTED_SCOPE) {
3820 if ( ! printed_private) {
3821 out_printf (outh, "\t/*< private >*/\n");
3822 printed_private = TRUE;
3824 put_variable ((Variable *)n, outh);
3828 always_private_struct) {
3829 if ( ! printed_private)
3830 out_printf (outh, "\t/*< private >*/\n");
3831 out_printf (outh, "\t%sPrivate *_priv;\n", typebase);
3833 out_printf (outh, "};\n");
3838 /* if we are to stick this into the private
3839 header, if not stick it directly into the
3846 out_printf (outfp, "struct _%sPrivate {\n",
3850 for(li=c->nodes; li; li=li->next) {
3852 Variable *v = (Variable *)n;
3853 if(n->type == VARIABLE_NODE &&
3854 v->scope == PRIVATE_SCOPE) {
3855 out_addline_infile(outfp, v->line_no);
3856 put_variable(v, outfp);
3859 out_addline_outfile(outfp);
3861 out_printf(outfp, "};\n");
3864 out_printf(outh, "\n/*\n"
3865 " * Class definition\n"
3867 out_printf(outh, "typedef struct _%sClass %sClass;\n",
3868 typebase, typebase);
3870 "struct _%sClass {\n\t%sClass __parent__;\n",
3871 typebase, ptypebase);
3872 for(li = c->nodes; li != NULL; li = li->next) {
3874 if(n->type == METHOD_NODE)
3875 put_vs_method((Method *)n);
3877 /* If BonoboX type class put down the epv */
3878 if (c->bonobo_object_class != NULL) {
3880 "\t/* Bonobo object epv */\n"
3881 "\tPOA_%s__epv _epv;\n",
3882 c->bonobo_object_class);
3884 /* put class scope variables */
3885 for (li = c->nodes; li != NULL; li = li->next) {
3887 Variable *v = (Variable *)n;
3888 if (n->type == VARIABLE_NODE &&
3889 v->scope == CLASS_SCOPE)
3890 put_variable ((Variable *)n, outh);
3892 out_printf (outh, "};\n\n");
3894 out_printf (out, "/* here are local prototypes */\n");
3895 if (set_properties > 0) {
3896 out_printf (out, "static void ___object_set_property "
3897 "(GObject *object, guint property_id, "
3898 "const GValue *value, GParamSpec *pspec);\n");
3900 if (get_properties > 0) {
3901 out_printf (out, "static void ___object_get_property "
3902 "(GObject *object, guint property_id, "
3903 "GValue *value, GParamSpec *pspec);\n");
3906 out_printf (outh, "\n/*\n"
3907 " * Public methods\n"
3910 if (!overrode_get_type) {
3912 * For ordinary "static" types it should be safe to mark the
3913 * get_type implementation as const, since the get_type
3914 * function return really is constant at the call boundary
3915 * (even though there is an initial setup on the first call).
3916 * But for dynamic types, since the registration is explicitly
3917 * separated, we need to settle for "pure" as the results of
3918 * get_type differ before and after type registration.
3920 out_printf(outh, "GType\t%s_get_type\t(void) %s;\n", funcbase,
3921 c->dynamic ? "G_GNUC_PURE" : "G_GNUC_CONST");
3925 out_printf(outh, "void\t%s_register_type\t(GTypeModule *);\n",
3929 for(li = c->nodes; li != NULL; li = li->next) {
3931 if(n->type == METHOD_NODE) {
3932 put_pub_method((Method *)n);
3933 put_prot_method((Method *)n);
3934 put_priv_method_prot((Method *)n);
3938 /* this idea is less and less apealing to me */
3940 out_printf (outh, "\n/*\n"
3941 " * Signal connection wrapper macros\n"
3944 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3945 put_signal_macros (c, TRUE);
3946 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3947 put_signal_macros (c, FALSE);
3948 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n");
3950 put_signal_macros (c, FALSE);
3951 out_printf(outh, "\n");
3954 out_printf (out, "\n/*\n"
3955 " * Signal connection wrapper macro shortcuts\n"
3957 put_local_signal_macros (c);
3958 out_printf(outh, "\n");
3961 /* argument wrapping macros */
3962 if(get_properties > 0 || set_properties > 0) {
3963 out_printf(outh, "\n/*\n"
3964 " * Argument wrapping macros\n"
3967 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3968 put_argument_gnu_wrappers(c);
3969 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3970 put_argument_nongnu_wrappers(c);
3971 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n");
3973 put_argument_nongnu_wrappers(c);
3978 for(li = c->nodes; li != NULL; li = li->next) {
3980 if(n->type == METHOD_NODE)
3981 add_signal_prots((Method *)n);
3987 if(any_method_to_alias(c)) {
3988 out_printf (out, "/* Short form macros */\n");
3989 make_method_aliases (c);
3992 add_interface_inits (c);
3994 if (!overrode_get_type) {
3995 if (c->bonobo_object_class != NULL)
3996 add_bonobo_object_get_type();
3997 else if (c->dynamic)
3998 add_dynamic_get_type();
4003 out_printf (out, "/* a macro for creating a new object of our type */\n");
4005 "#define GET_NEW ((%s *)g_object_new(%s_get_type(), NULL))\n\n",
4006 typebase, funcbase);
4008 out_printf (out, "/* a function for creating a new object of our type */\n");
4009 out_printf (out, "#include <stdarg.h>\n");
4011 "static %s * GET_NEW_VARG (const char *first, ...)%s;\n"
4012 "static %s *\nGET_NEW_VARG (const char *first, ...)\n"
4013 "{\n\t%s *ret;\n\tva_list ap;\n"
4014 "\tva_start (ap, first);\n"
4015 "\tret = (%s *)g_object_new_valist (%s_get_type (), "
4018 "\treturn ret;\n}\n\n",
4020 no_gnu ? "" : " G_GNUC_UNUSED",
4021 typebase, typebase, typebase, funcbase);
4025 out_printf (out, "/* a function to connect glade callback */\n");
4026 out_printf (out,"static void\n"
4027 "___glade_xml_connect_foreach(const gchar *handler_name,\n"
4028 "GObject *object,\n"
4029 "const gchar *signal_name,\n"
4030 "const gchar *signal_data,\n"
4031 "GObject *connect_object,\n"
4033 "gpointer user_data)\n"
4035 "\tstatic GModule * allsymbols = NULL;\n"
4037 "\tif (!allsymbols) allsymbols = g_module_open(NULL, 0);\n"
4038 "\tif (allsymbols) {\n"
4039 "\t\tgchar * func_name = g_strdup_printf(\"%s_%%s\", handler_name);\n"
4040 "\t\tGCallback func;\n"
4042 "\t\tif (!g_module_symbol(allsymbols, func_name, (gpointer)&func)){\n"
4043 "\t\t\tif (!g_module_symbol(allsymbols, handler_name, (gpointer)&func)) {\n"
4044 "\t\t\t\tg_warning(\"could not find signal handler '%%s'.\", func_name);\n"
4045 "\t\t\t\tg_free(func_name);\n"
4050 "\t\t\tg_signal_connect_data(object, signal_name, func, user_data, NULL, G_CONNECT_AFTER | G_CONNECT_SWAPPED);\n"
4052 "\t\t\tg_signal_connect_data(object, signal_name, func, user_data, NULL, G_CONNECT_SWAPPED);\n"
4053 "\t\tg_free(func_name);\n"
4060 for (li = nodes; li != NULL; li = li->next) {
4061 Node *node = li->data;
4062 if (node->type == CCODE_NODE) {
4063 CCode *cc = (CCode *)node;
4064 if (cc->cctype == AD_CCODE)
4065 print_ccode_block (cc);
4069 if (need_constructor)
4070 add_constructor (c);
4080 if(set_properties > 0) {
4081 add_getset_arg(c, TRUE);
4084 if(get_properties > 0) {
4085 add_getset_arg(c, FALSE);
4088 for(li = c->nodes; li != NULL; li = li->next) {
4090 if(n->type == METHOD_NODE)
4091 put_method((Method *)n);
4094 add_bad_hack_to_avoid_unused_warnings(c);
4098 print_useful_macros(void)
4100 int major = 0, minor = 0, pl = 0;
4103 sscanf (VERSION, "%d.%d.%d", &major, &minor, &pl);
4104 out_printf (out, "#define GOB_VERSION_MAJOR %d\n", major);
4105 out_printf (out, "#define GOB_VERSION_MINOR %d\n", minor);
4106 out_printf (out, "#define GOB_VERSION_PATCHLEVEL %d\n\n", pl);
4108 /* Useful priv macro thingie */
4109 /* FIXME: this should be done the same way that priv is, as a var,
4111 out_printf (out, "#define selfp (self->_priv)\n\n");
4115 print_more_useful_macros (void)
4118 out_printf (out, "#define ___GOB_LIKELY(expr) (expr)\n");
4119 out_printf (out, "#define ___GOB_UNLIKELY(expr) (expr)\n");
4121 out_printf (out, "#ifdef G_LIKELY\n");
4122 out_printf (out, "#define ___GOB_LIKELY(expr) G_LIKELY(expr)\n");
4123 out_printf (out, "#define ___GOB_UNLIKELY(expr) G_UNLIKELY(expr)\n");
4124 out_printf (out, "#else /* ! G_LIKELY */\n");
4125 out_printf (out, "#define ___GOB_LIKELY(expr) (expr)\n");
4126 out_printf (out, "#define ___GOB_UNLIKELY(expr) (expr)\n");
4127 out_printf (out, "#endif /* G_LIKELY */\n");
4132 print_file_comments(void)
4134 out_printf(outh, "/* Generated by GOB (v%s)"
4135 " (do not edit directly) */\n\n", VERSION);
4137 out_printf(outph, "/* Generated by GOB (v%s)"
4138 " (do not edit directly) */\n\n", VERSION);
4139 out_printf(out, "/* Generated by GOB (v%s)"
4140 " (do not edit directly) */\n\n", VERSION);
4142 out_printf(out, "/* End world hunger, donate to the World Food Programme, http://www.wfp.org */\n\n");
4146 print_includes(void)
4148 gboolean found_header;
4151 /* We may need string.h for memset */
4152 if ( ! g_list_find_custom(include_files, "string.h", (GCompareFunc)strcmp)) {
4153 out_printf(out, "#include <string.h> /* memset() */\n\n");
4156 p = g_strconcat(filebase, ".h", NULL);
4157 found_header = TRUE;
4158 if( ! g_list_find_custom(include_files, p, (GCompareFunc)strcmp)) {
4159 out_printf(out, "#include \"%s.h\"\n\n", filebase);
4160 found_header = FALSE;
4164 /* if we are creating a private header see if it was included */
4166 char sep[2] = {0,0};
4169 p = g_strconcat(filebase, sep, "private.h", NULL);
4170 if( ! g_list_find_custom(include_files, p,
4171 (GCompareFunc)strcmp)) {
4172 out_printf(out, "#include \"%s%sprivate.h\"\n\n",
4176 error_printf(GOB_WARN, 0,
4177 "Implicit private header include "
4179 "\tsource file, while public "
4180 "header is at a custom location, "
4182 "\texplicitly include "
4183 "the private header below the "
4191 print_header_prefixes(void)
4195 p = replace_sep(((Class *)class)->otype, '_');
4197 out_printf(outh, "#ifndef __%s_H__\n#define __%s_H__\n\n", p, p);
4199 out_printf(outph, "#ifndef __%s_PRIVATE_H__\n"
4200 "#define __%s_PRIVATE_H__\n\n"
4201 "#include \"%s.h\"\n\n", p, p, filebase);
4204 if( ! no_extern_c) {
4205 out_printf(outh, "#ifdef __cplusplus\n"
4207 "#endif /* __cplusplus */\n\n");
4209 out_printf(outph, "#ifdef __cplusplus\n"
4211 "#endif /* __cplusplus */\n\n");
4216 print_header_postfixes(void)
4219 out_printf(outh, "\n#ifdef __cplusplus\n"
4221 "#endif /* __cplusplus */\n");
4222 out_printf(outh, "\n#endif\n");
4225 out_printf(outph, "\n#ifdef __cplusplus\n"
4227 "#endif /* __cplusplus */\n");
4228 out_printf(outph, "\n#endif\n");
4237 /* print the AT_CCODE and CT_CCODE blocks */
4238 for(li = nodes; li != NULL; li = li->next) {
4239 Node *node = li->data;
4240 if(node->type == CCODE_NODE) {
4241 CCode *cc = (CCode *)node;
4242 if (cc->cctype == AT_CCODE ||
4243 cc->cctype == CT_CCODE)
4244 print_ccode_block((CCode *)node);
4250 print_header_top(void)
4254 /* mandatory includes */
4255 out_printf (outh, "#include <glib.h>\n");
4256 out_printf (outh, "#include <glib-object.h>\n");
4258 /* print the HT_CCODE blocks */
4259 for (li = nodes; li != NULL; li = li->next) {
4260 Node *node = li->data;
4261 if (node->type == CCODE_NODE) {
4262 CCode *cc = (CCode *)node;
4263 if (cc->cctype == HT_CCODE)
4264 print_ccode_block ((CCode *)node);
4270 print_enum (EnumDef *enode)
4277 funcprefix = replace_sep (enode->etype, '_');
4278 gob_strdown (funcprefix);
4279 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
4281 type = remove_sep (enode->etype);
4283 out_printf (outh, "\ntypedef enum {\n");
4285 for (li = enode->values; li != NULL; li = li->next) {
4286 EnumValue *value = li->data;
4288 char *sname = gob_strdown (g_strdup (value->name));
4290 while ((p = strchr (sname, '_')) != NULL)
4293 out_printf (outh, "\t%s_%s", enode->prefix, value->name);
4294 if (value->value != NULL)
4295 out_printf (outh, " = %s", value->value);
4296 if (li->next != NULL)
4297 out_printf (outh, ",\n");
4299 out_printf (outh, "\n");
4301 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
4302 enode->prefix, value->name,
4303 enode->prefix, value->name,
4309 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
4311 out_printf (outh, "} %s;\n", type);
4313 str = make_pre_macro (enode->etype, "TYPE");
4314 out_printf (outh, "#define %s ", str);
4317 out_printf (outh, "%s_get_type()\n", funcprefix);
4318 out_printf (outh, "GType %s_get_type (void) G_GNUC_CONST;\n\n", funcprefix);
4321 "GType\n%s_get_type (void)\n"
4323 "\tstatic GType type = 0;\n"
4324 "\tif ___GOB_UNLIKELY(type == 0)\n"
4325 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
4328 funcprefix, type, funcprefix);
4330 g_free (funcprefix);
4335 print_flags (Flags *fnode)
4343 funcprefix = replace_sep (fnode->ftype, '_');
4344 gob_strdown (funcprefix);
4345 out_printf (out, "static const GFlagsValue _%s_values[] = {\n",
4347 type = remove_sep (fnode->ftype);
4349 out_printf (outh, "\ntypedef enum {\n");
4351 for (i = 0, li = fnode->values; li != NULL; i++, li = li->next) {
4352 const char *name = li->data;
4354 char *sname = gob_strdown (g_strdup (name));
4356 while ((p = strchr (sname, '_')) != NULL)
4359 out_printf (outh, "\t%s_%s = 1<<%d",
4360 fnode->prefix, name, i);
4361 if (li->next != NULL)
4362 out_printf (outh, ",\n");
4364 out_printf (outh, "\n");
4366 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
4367 fnode->prefix, name,
4368 fnode->prefix, name,
4374 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
4376 out_printf (outh, "} %s;\n", type);
4378 str = make_pre_macro (fnode->ftype, "TYPE");
4379 out_printf (outh, "#define %s ", str);
4382 out_printf (outh, "%s_get_type()\n", funcprefix);
4383 out_printf (outh, "GType %s_get_type (void) G_GNUC_CONST;\n\n", funcprefix);
4386 "GType\n%s_get_type (void)\n"
4388 "\tstatic GType type = 0;\n"
4389 "\tif ___GOB_UNLIKELY(type == 0)\n"
4390 "\t\ttype = g_flags_register_static (\"%s\", _%s_values);\n"
4393 funcprefix, type, funcprefix);
4395 g_free (funcprefix);
4400 print_error (Error *enode)
4407 funcprefix = replace_sep (enode->etype, '_');
4408 gob_strdown (funcprefix);
4409 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
4411 type = remove_sep (enode->etype);
4413 out_printf (outh, "\ntypedef enum {\n");
4415 for (li = enode->values; li != NULL; li = li->next) {
4416 const char *name = li->data;
4418 char *sname = gob_strdown (g_strdup (name));
4420 while ((p = strchr (sname, '_')) != NULL)
4423 out_printf (outh, "\t%s_%s", enode->prefix, name);
4424 if (li->next != NULL)
4425 out_printf (outh, ",\n");
4427 out_printf (outh, "\n");
4429 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
4430 enode->prefix, name,
4431 enode->prefix, name,
4437 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
4439 out_printf (outh, "} %s;\n", type);
4441 str = make_pre_macro (enode->etype, "TYPE");
4442 out_printf (outh, "#define %s ", str);
4445 out_printf (outh, "%s_get_type ()\n", funcprefix);
4446 out_printf (outh, "GType %s_get_type (void) G_GNUC_CONST;\n\n", funcprefix);
4449 "GType\n%s_get_type (void)\n"
4451 "\tstatic GType type = 0;\n"
4452 "\tif ___GOB_UNLIKELY(type == 0)\n"
4453 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
4456 funcprefix, type, funcprefix);
4458 out_printf (outh, "#define %s %s_quark ()\n", enode->prefix, funcprefix);
4459 out_printf (outh, "GQuark %s_quark (void);\n\n", funcprefix);
4461 str = replace_sep (enode->etype, '-');
4465 "GQuark\n%s_quark (void)\n"
4467 "\tstatic GQuark q = 0;\n"
4469 "\t\tq = g_quark_from_static_string (\"%s\");\n"
4476 g_free (funcprefix);
4481 generate_outfiles(void)
4485 print_file_comments();
4491 print_header_prefixes();
4493 print_useful_macros();
4497 print_more_useful_macros ();
4499 for (li = nodes; li != NULL; li = li->next) {
4500 Node *node = li->data;
4501 if (node->type == CCODE_NODE) {
4502 CCode *cc = (CCode *)node;
4503 if (cc->cctype != HT_CCODE &&
4504 cc->cctype != AT_CCODE &&
4505 cc->cctype != AD_CCODE)
4506 print_ccode_block ((CCode *)node);
4507 } else if (node->type == CLASS_NODE) {
4508 print_class_block ((Class *)node);
4509 } else if (node->type == ENUMDEF_NODE) {
4510 print_enum ((EnumDef *)node);
4511 } else if (node->type == FLAGS_NODE) {
4512 print_flags ((Flags *)node);
4513 } else if (node->type == ERROR_NODE) {
4514 print_error ((Error *)node);
4516 g_assert_not_reached();
4520 print_header_postfixes();
4526 fprintf(stderr, "Gob version %s\n\n", VERSION);
4527 fprintf(stderr, "gob [options] file.gob\n\n");
4528 fprintf(stderr, "Options:\n"
4529 "\t--help,-h,-? Display this help\n"
4530 "\t--version Display version\n"
4531 "\t--exit-on-warn,-w Exit with an error on warnings\n"
4532 "\t--no-exit-on-warn Don't exit on warnings [default]\n"
4533 "\t--for-cpp Create C++ files\n"
4534 "\t--no-extern-c Never print extern \"C\" into the "
4536 "\t--no-gnu Never use GNU extentions\n"
4537 "\t--no-touch Don't touch output files unless they "
4539 "\t changed (implies --no-touch-headers)\n"
4540 "\t--no-touch-headers Don't touch headers unless they "
4542 "\t--always-private-header Always create a private header "
4544 "\t even if it would be empty\n"
4545 "\t--ondemand-private-header Create private header only when "
4548 "\t--no-private-header Don't create a private header, "
4550 "\t structure and protected "
4551 "prototypes inside c file\n"
4552 "\t--always-private-struct Always create a private pointer "
4554 "\t the object structure\n"
4555 "\t--m4 Preprocess source with m4. "
4556 "Following args will\n"
4557 "\t be passed to m4\n"
4558 "\t--m4-dir Print directory that will be "
4561 "\t--no-write,-n Don't write output files, just "
4563 "\t--no-lines Don't print '#line' to output\n"
4564 "\t--no-self-alias Don't create self type and macro "
4566 "\t--no-kill-underscores Ignored for compatibility\n"
4567 "\t-o,--output-dir The directory where output "
4568 "should be placed\n"
4569 "\t--file-sep[=c] replace default \'-\' file "
4570 "name separator\n\n"
4571 "\t--gtk3 Use gtk+3\n"
4573 fprintf(stderr, "End world hunger, donate to the World Food Programme, http://www.wfp.org\n");
4577 parse_options(int argc, char *argv[])
4580 int got_file = FALSE;
4581 int no_opts = FALSE;
4582 int m4_opts = FALSE; /* if we are just passing on args to m4 */
4586 for(i = 1 ; i < argc; i++) {
4588 char *new_commandline;
4589 g_assert(m4_commandline!=NULL);
4591 /* check whether this one looks like the filename */
4592 if((!strcmp(argv[i],"-") || argv[i][0] != '-')
4594 const gchar *m4_flags=use_m4_clean?"":M4_FLAGS;
4598 /* insert flags before the filename */
4599 new_commandline=g_strconcat(m4_commandline,
4607 /* just an ordinary option */
4609 new_commandline=g_strconcat(m4_commandline,
4614 /* free old commandline */
4615 g_free(m4_commandline);
4616 m4_commandline=new_commandline;
4618 } else if(no_opts ||
4619 argv[i][0] != '-') {
4622 fprintf(stderr, "Specify only one file!\n");
4628 } else if(strcmp(argv[i], "--help")==0) {
4631 } else if(strcmp(argv[i], "--version")==0) {
4632 fprintf(stderr, "Gob version %s\n", VERSION);
4634 } else if(strcmp(argv[i], "--exit-on-warn")==0) {
4635 exit_on_warn = TRUE;
4636 } else if(strcmp(argv[i], "--no-exit-on-warn")==0) {
4637 exit_on_warn = FALSE;
4638 } else if(strcmp(argv[i], "--for-cpp")==0) {
4640 } else if(strcmp(argv[i], "--no-touch")==0) {
4642 no_touch_headers = TRUE;
4643 } else if(strcmp(argv[i], "--no-touch-headers")==0) {
4644 no_touch_headers = TRUE;
4645 } else if(strcmp(argv[i], "--ondemand-private-header")==0) {
4646 private_header = PRIVATE_HEADER_ONDEMAND;
4647 } else if(strcmp(argv[i], "--always-private-header")==0) {
4648 private_header = PRIVATE_HEADER_ALWAYS;
4649 } else if(strcmp(argv[i], "--no-private-header")==0) {
4650 private_header = PRIVATE_HEADER_NEVER;
4651 } else if(strcmp(argv[i], "--no-gnu")==0) {
4653 } else if(strcmp(argv[i], "--no-extern-c")==0) {
4655 } else if(strcmp(argv[i], "--no-write")==0) {
4657 } else if(strcmp(argv[i], "--no-lines")==0) {
4659 } else if(strcmp(argv[i], "--no-self-alias")==0) {
4660 no_self_alias = TRUE;
4661 } else if(strcmp(argv[i], "--no-kill-underscores")==0) {
4663 } else if(strcmp(argv[i], "--always-private-struct")==0) {
4664 always_private_struct = TRUE;
4665 } else if(strcmp(argv[i], "--m4-dir")==0) {
4666 printf("%s\n",M4_INCLUDE_DIR);
4668 } else if(strcmp(argv[i], "--m4")==0) {
4672 m4_commandline=g_strdup(M4_COMMANDLINE);
4673 } else if(strcmp(argv[i], "--m4-clean")==0) {
4677 m4_commandline=g_strdup(M4_COMMANDLINE);
4678 } else if (strcmp (argv[i], "-o") == 0 ||
4679 strcmp (argv[i], "--output-dir") == 0) {
4681 output_dir = g_strdup (argv[i+1]);
4686 } else if (strncmp (argv[i], "-o=", strlen ("-o=")) == 0 ||
4689 strlen ("--output-dir=")) == 0) {
4690 char *p = strchr (argv[i], '=');
4691 g_assert (p != NULL);
4692 output_dir = g_strdup (p+1);
4693 } else if (strncmp (argv[i], "--file-sep=",
4694 strlen ("--file-sep=")) == 0) {
4695 char *p = strchr (argv[i], '=');
4696 g_assert (p != NULL);
4698 } else if (strncmp (argv[i], "--file-sep",
4699 strlen ("--file-sep")) == 0) {
4701 file_sep = (argv[i+1])[0];
4706 } else if(strcmp(argv[i], "--gtk3")==0) {
4708 } else if(strcmp(argv[i], "--")==0) {
4709 /*further arguments are files*/
4711 } else if(strncmp(argv[i], "--", 2)==0) {
4712 /*unknown long option*/
4713 fprintf(stderr, "Unknown option '%s'!\n", argv[i]);
4717 /*by now we know we have a string starting with
4718 - which is a short option string*/
4720 for(p = argv[i] + 1; *p; p++) {
4734 "Unknown option '%c'!\n", *p);
4743 /* if we are using m4, and got no filename, append m4 flags now */
4744 if(!got_file && use_m4 && !use_m4_clean) {
4745 char *new_commandline;
4746 new_commandline=g_strconcat(m4_commandline,
4750 g_free(m4_commandline);
4751 m4_commandline=new_commandline;
4757 compare_and_move (const char *old_filename)
4759 char *new_filename = g_strconcat (old_filename, "#gob#", NULL);
4761 gboolean equal = FALSE;
4763 old_f = fopen (old_filename, "r");
4766 gboolean error = FALSE;
4768 new_f = fopen (new_filename, "r");
4777 new_n = fread (new_buf, 1, sizeof (new_buf), new_f);
4778 if (ferror (new_f)) {
4780 error_printf (GOB_ERROR, 0,
4781 "Can't read %s: %s",
4783 g_strerror (errno));
4787 old_n = fread (old_buf, 1, sizeof (old_buf), old_f);
4789 || feof (new_f) != feof (old_f)
4791 || memcmp (new_buf, old_buf, new_n) != 0)
4800 error_printf (GOB_ERROR, 0, "Can't open %s: %s",
4801 new_filename, g_strerror (errno));
4809 if (! equal && unlink (old_filename) != 0) {
4810 error_printf (GOB_ERROR, 0, "Can't remove %s: %s",
4811 old_filename, g_strerror (errno));
4817 if (unlink (new_filename) != 0)
4818 error_printf (GOB_ERROR, 0, "Can't remove %s: %s",
4819 new_filename, g_strerror (errno));
4821 if (rename (new_filename, old_filename) != 0)
4822 error_printf (GOB_ERROR, 0, "Can't rename %s to %s: %s",
4823 new_filename, old_filename,
4824 g_strerror (errno));
4828 g_free (new_filename);
4832 main(int argc, char *argv[])
4834 parse_options(argc, argv);
4837 yyin = popen(m4_commandline, "r");
4839 fprintf(stderr, "Error: can't open pipe from '%s'\n",
4843 } else if(filename) {
4844 yyin = fopen(filename, "r");
4846 fprintf(stderr, "Error: can't open file '%s'\n",
4855 /* This is where parsing is done */
4858 error_print (GOB_ERROR, 0, "Parsing errors, quitting");
4860 /* close input file */
4861 if(use_m4) pclose(yyin);
4866 error_print (GOB_ERROR, 0, "no class defined");
4869 exit_on_error = FALSE;
4871 signals = count_signals ((Class *)class);
4872 set_properties = count_set_properties ((Class *)class) +
4873 count_set_arguments ((Class *)class);
4874 get_properties = count_get_properties ((Class *)class) +
4875 count_get_arguments ((Class *)class);
4876 overrides = count_overrides ((Class *)class);
4877 privates = count_privates ((Class *)class);
4878 protecteds = count_protecteds ((Class *)class);
4879 unreftors = count_unreftors ((Class *)class);
4880 destructors = count_destructors ((Class *)class);
4881 initializers = count_initializers ((Class *)class);
4882 glade_widgets = count_glade_widgets ((Class *)class);
4883 overrode_get_type = find_get_type ((Class *)class);
4886 make_inits ((Class *)class);
4888 find_constructor ((Class *)class);
4889 if (user_constructor != NULL)
4890 need_constructor = TRUE;
4892 find_dispose ((Class *)class);
4893 if (unreftors > 0 ||
4894 dispose_handler != NULL ||
4895 user_dispose_method != NULL)
4896 need_dispose = TRUE;
4898 find_finalize ((Class *)class);
4899 if (destructors > 0 ||
4901 user_finalize_method != NULL) {
4902 need_finalize = TRUE;
4905 check_bad_symbols ((Class *)class);
4906 check_duplicate_symbols ((Class *)class);
4907 check_duplicate_overrides ((Class *)class);
4908 check_duplicate_signals_args ((Class *)class);
4909 check_public_new ((Class *)class);
4910 check_vararg ((Class *)class);
4911 check_firstarg ((Class *)class);
4912 check_nonvoidempty ((Class *)class);
4913 check_signal_args ((Class *)class);
4914 check_property_types ((Class *)class);
4915 check_argument_types ((Class *)class);
4916 check_func_arg_checks ((Class *)class);
4917 check_func_attrs ((Class *)class);
4918 check_for_class_destructors ((Class *)class);
4920 exit_on_error = TRUE;
4925 any_special = setup_special_array ((Class *)class, special_array);
4929 generate_outfiles ();
4940 compare_and_move (outfilebase);
4942 compare_and_move (outfilephbase);
4944 if (no_touch_headers)
4945 compare_and_move (outfilehbase);