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 (void)
1128 for (li = ((Class *)class)->interfaces;
1131 char *name = replace_sep (li->data, '_');
1133 "\t\tstatic const GInterfaceInfo %s_info = {\n"
1134 "\t\t\t(GInterfaceInitFunc) ___%s_init,\n"
1144 add_interfaces (void)
1147 for (li = ((Class *)class)->interfaces;
1150 char *name = replace_sep (li->data, '_');
1151 char *type = make_pre_macro (li->data, "TYPE");
1154 "\t\tg_type_add_interface_static (type,\n"
1156 "\t\t\t&%s_info);\n",
1166 add_dynamic_interfaces(void)
1168 GList *li = ((Class *)class)->interfaces;
1172 * Hack to work around bug in g_type_module_add_interface,
1173 * which will fail to add an interface to types that derive
1174 * from something that also implements the same interface.
1176 * The actual GType system does not have any such problem,
1177 * and the GTypeModule implementation details relied upon
1178 * here have not changed once since the feature was first
1179 * implemented almost 20 years ago.
1181 out_printf(out, "\t\tstruct _ModuleInterfaceInfo {\n"
1182 "\t\t\tgboolean loaded;\n"
1183 "\t\t\tGType instance_type;\n"
1184 "\t\t\tGType interface_type;\n"
1185 "\t\t\tGInterfaceInfo info;\n"
1186 "\t\t} *modinfo;\n");
1189 for (; li; li = li->next) {
1190 char *name = replace_sep(li->data, '_');
1191 char *type = make_pre_macro(li->data, "TYPE");
1193 out_printf(out, "\n"
1194 "\t\tmodinfo = g_malloc(sizeof *modinfo);\n"
1195 "\t\tmodinfo->loaded = TRUE;\n"
1196 "\t\tmodinfo->instance_type = %s_type_id;\n"
1197 "\t\tmodinfo->interface_type = %s;\n"
1198 "\t\tmodinfo->info = %s_info;\n"
1199 "\t\tg_type_add_interface_dynamic\n"
1200 "\t\t\t( modinfo->instance_type\n"
1201 "\t\t\t, modinfo->interface_type\n"
1202 "\t\t\t, G_TYPE_PLUGIN(type_module)\n"
1204 "\t\ttype_module->interface_infos = g_slist_prepend\n"
1205 "\t\t\t( type_module->interface_infos\n"
1207 "\t\t\t);\n", funcbase, type, name);
1217 /*char *chunk_size = ((Class*)class)->chunk_size;*/
1221 "%s_get_type (void)\n"
1223 "\tstatic GType type = 0;\n\n"
1224 "\tif ___GOB_UNLIKELY(type == 0) {\n"
1225 "\t\tstatic const GTypeInfo info = {\n"
1226 "\t\t\tsizeof (%sClass),\n"
1227 "\t\t\t(GBaseInitFunc) NULL,\n"
1228 "\t\t\t(GBaseFinalizeFunc) NULL,\n"
1229 "\t\t\t(GClassInitFunc) %s_class_init,\n"
1230 "\t\t\t(GClassFinalizeFunc) NULL,\n"
1231 "\t\t\tNULL /* class_data */,\n"
1232 "\t\t\tsizeof (%s),\n"
1233 "\t\t\t%d /* n_preallocs */,\n"
1234 "\t\t\t(GInstanceInitFunc) %s_init,\n"
1237 funcbase, typebase, funcbase, typebase, prealloc, funcbase);
1239 add_interface_infos ();
1242 "\t\ttype = g_type_register_static (%s, \"%s\", &info, (GTypeFlags)%s);\n",
1243 pmacrotype, typebase, ((Class *)class)->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0");
1251 "\t\tgtk_type_set_chunk_alloc(type, %s);\n"
1253 chunk_size, chunk_size);
1263 add_dynamic_get_type (void)
1266 "static GType %s_type_id;\n\n"
1268 "%s_get_type (void)\n"
1270 "\treturn %s_type_id;\n"
1272 funcbase, funcbase, funcbase);
1276 "%s_register_type (GTypeModule *type_module)\n"
1278 "\tstatic const GTypeInfo info = {\n"
1279 "\t\tsizeof (%sClass),\n"
1280 "\t\t(GBaseInitFunc) NULL,\n"
1281 "\t\t(GBaseFinalizeFunc) NULL,\n"
1282 "\t\t(GClassInitFunc) %s_class_init,\n"
1283 "\t\t(GClassFinalizeFunc) NULL,\n"
1284 "\t\tNULL /* class_data */,\n"
1285 "\t\tsizeof (%s),\n"
1286 "\t\t%d /* n_preallocs */,\n"
1287 "\t\t(GInstanceInitFunc) %s_init,\n"
1290 funcbase, typebase, funcbase, typebase, prealloc, funcbase);
1292 add_interface_infos();
1295 "\t%s_type_id = g_type_module_register_type(\n"
1296 "\t\ttype_module,\n"
1300 "\t\t(GTypeFlags)%s\n"
1303 funcbase, pmacrotype, typebase,
1304 ((Class *)class)->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0");
1306 add_dynamic_interfaces();
1314 add_bonobo_object_get_type (void)
1316 /* char *chunk_size = ((Class*)class)->chunk_size; */
1317 /* _vicious_ spanks seth with a rusty nail
1319 "\n#warning \"Bonobo isn't fully ported to glib 2.0 and "
1320 "gob2 doesn't officially support it yet. It'd be safer "
1321 "and a lot more fun to blow goats.\"\n");
1326 "%s_get_type (void)\n" /* 1 */
1328 "\tstatic GType type = 0;\n\n"
1329 "\tif ___GOB_UNLIKELY(type == 0) {\n"
1330 "\t\tstatic const GTypeInfo info = {\n"
1331 "\t\t\tsizeof (%sClass),\n" /* 2 */
1332 "\t\t\t(GBaseInitFunc) NULL,\n"
1333 "\t\t\t(GBaseFinalizeFunc) NULL,\n"
1334 "\t\t\t(GClassInitFunc) %s_class_init,\n" /* 3 */
1335 "\t\t\tNULL, /* class_finalize */\n"
1336 "\t\t\tNULL, /* class_data */\n"
1337 "\t\t\tsizeof (%s),\n" /* 4 */
1338 "\t\t\t0, /* n_preallocs */\n"
1339 "\t\t\t(GInstanceInitFunc) %s_init,\n" /* 5 */
1348 add_interface_infos ();
1351 "\t\ttype = bonobo_type_unique (\n"
1352 "\t\t\tBONOBO_OBJECT_TYPE,\n"
1353 "\t\t\tPOA_%s__init, NULL,\n" /* 1 */
1354 "\t\t\tG_STRUCT_OFFSET (%sClass, _epv),\n" /* 2 */
1355 "\t\t\t&info, \"%s\");\n", /* 3 */
1356 ((Class*)class)->bonobo_object_class /* 1 */,
1365 "\t\tgtk_type_set_chunk_alloc(type, %s);\n"
1367 chunk_size, chunk_size);
1376 add_overrides(Class *c, const char *oname,
1377 gboolean did_base_obj)
1383 done = g_hash_table_new (g_str_hash, g_str_equal);
1385 s = g_strdup ("GObject");
1386 g_hash_table_insert (done, s, s);
1388 for (li = c->nodes; li != NULL; li = li->next) {
1391 Method *m = (Method *)n;
1392 if(n->type != METHOD_NODE ||
1393 m->method != OVERRIDE_METHOD)
1396 s = remove_sep(m->otype);
1398 if(g_hash_table_lookup(done, s)) {
1402 g_hash_table_insert(done, s, s);
1404 f = replace_sep(m->otype, '_');
1407 out_printf(out, "\t%sClass *%s_class = (%sClass *)%s;\n",
1412 g_hash_table_foreach (done, (GHFunc)g_free, NULL);
1413 g_hash_table_destroy (done);
1417 make_run_signal_flags(Method *m, gboolean last)
1432 gs = g_string_new(NULL);
1435 g_string_assign(gs, "G_SIGNAL_RUN_LAST");
1437 g_string_assign(gs, "G_SIGNAL_RUN_FIRST");
1439 if(m->scope == PUBLIC_SCOPE)
1440 g_string_append(gs, " | G_SIGNAL_ACTION");
1442 for(li = m->flags; li; li = li->next) {
1443 char *flag = li->data;
1445 for(i=0;flags[i];i++) {
1446 if(strcmp(flags[i], flag)==0)
1449 /* if we haven't found it in our list */
1451 error_printf(GOB_WARN, m->line_no,
1452 "Unknown flag '%s' used, "
1453 "perhaps it was misspelled",
1456 g_string_sprintfa(gs, " | G_SIGNAL_%s", flag);
1460 char *ret = gs->str;
1461 g_string_free(gs, FALSE);
1468 add_signals(Class *c)
1472 out_printf(out, "\n");
1473 for(li=c->nodes;li;li=g_list_next(li)) {
1475 char *mar, *sig, *flags;
1476 gboolean is_none, last = FALSE;
1477 Method *m = (Method *)n;
1479 if(n->type != METHOD_NODE ||
1480 (m->method != SIGNAL_FIRST_METHOD &&
1481 m->method != SIGNAL_LAST_METHOD))
1484 if(m->method == SIGNAL_FIRST_METHOD)
1489 if(g_hash_table_lookup(marsh, m))
1490 mar = g_strconcat("___marshal_",
1491 (char *)g_hash_table_lookup(marsh, m),
1494 mar = g_strdup("g_cclosure_marshal_VOID__VOID");
1496 is_none = (strcmp(m->gtktypes->next->data, "NONE")==0);
1498 sig = g_strdup (m->id);
1500 flags = make_run_signal_flags (m, last);
1501 out_printf (out, "\tobject_signals[%s_SIGNAL] =\n"
1502 "\t\tg_signal_new (%s,\n"
1503 "\t\t\tG_TYPE_FROM_CLASS (g_object_class),\n"
1504 "\t\t\t(GSignalFlags)(%s),\n"
1505 "\t\t\tG_STRUCT_OFFSET (%sClass, %s),\n"
1506 "\t\t\tNULL, NULL,\n"
1508 "\t\t\tG_TYPE_%s, %d",
1509 sig, m->signal_name /*m->id* if not given signal_name*/,
1511 typebase, m->id, mar,
1512 (char *)m->gtktypes->data,
1513 is_none ? 0 : g_list_length(m->gtktypes->next));
1521 for(l = m->gtktypes->next; l != NULL; l = l->next) {
1522 char *str = l->data;
1523 if (strncmp (str, "BOXED_", 6) == 0)
1524 t = g_strdup (&(str[6]));
1526 t = g_strconcat ("G_TYPE_", str, NULL);
1527 out_printf (out, ",\n\t\t\t%s", t);
1532 out_printf(out, ");\n");
1534 if(strcmp(m->gtktypes->data, "NONE") != 0 ||
1537 out_printf(out, "\tif ___GOB_UNLIKELY(");
1538 if(strcmp(m->gtktypes->data, "NONE") != 0) {
1539 out_printf(out, "sizeof(");
1540 print_type(out, m->mtype, FALSE);
1541 out_printf(out, "%s",
1543 m->mtype->postfix : "");
1544 out_printf(out, ") != sizeof(%s) || ",
1545 get_cast(m->gtktypes->data, FALSE));
1548 for(al = m->args->next, gl = m->gtktypes->next;
1549 al != NULL && gl != NULL;
1550 al = al->next, gl = gl->next) {
1551 FuncArg *arg = al->data;
1552 char *gtkarg = gl->data;
1554 out_printf(out, "sizeof(");
1555 print_type(out, arg->atype, FALSE);
1556 out_printf(out, "%s",
1557 arg->atype->postfix ?
1558 arg->atype->postfix : "");
1559 out_printf(out, ") != sizeof(%s) || ",
1560 get_cast(gtkarg, FALSE));
1564 "parent_class == NULL /* avoid warning */");
1566 out_printf(out, ") {\n"
1567 "\t\tg_error(\"%s line %d: Type mismatch "
1568 "of \\\"%s\\\" signal signature\");\n"
1570 filename, m->line_no, m->id);
1577 set_def_handlers(Class *c, const char *oname)
1580 gboolean set_line = FALSE;
1582 out_printf(out, "\n");
1583 for(li = c->nodes; li; li = g_list_next(li)) {
1585 Method *m = (Method *)n;
1587 if(n->type != METHOD_NODE ||
1588 (m->method != SIGNAL_FIRST_METHOD &&
1589 m->method != SIGNAL_LAST_METHOD &&
1590 m->method != VIRTUAL_METHOD &&
1591 m->method != OVERRIDE_METHOD))
1594 if(m->line_no > 0 && m->cbuf) {
1595 out_addline_infile(out, m->line_no);
1597 } else if(set_line) {
1598 out_addline_outfile(out);
1603 if (m->method == OVERRIDE_METHOD) {
1605 s = replace_sep (m->otype, '_');
1609 dispose_handler != NULL &&
1610 strcmp (m->id, "dispose") == 0)
1611 out_printf (out, "\tg_object_class->dispose "
1613 else if (need_finalize &&
1615 strcmp(m->id, "finalize") == 0)
1617 "\tg_object_class->finalize = ___finalize;\n");
1618 else if (m->cbuf != NULL)
1620 "\t%s_class->%s = ___%x_%s_%s;\n",
1621 s, m->id, (guint)m->unique_id,
1624 out_printf(out, "\t%s_class->%s = NULL;\n",
1628 out_printf(out, "\t%s->%s = ___real_%s_%s;\n",
1632 out_printf(out, "\t%s->%s = NULL;\n",
1637 out_addline_outfile(out);
1641 make_argument (Argument *a)
1646 char *argflags[] = {
1654 flags = g_string_new ("(GParamFlags)(");
1656 if(a->get && a->set)
1657 g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
1659 g_string_append (flags, "G_PARAM_READABLE");
1661 g_string_append (flags, "G_PARAM_WRITABLE");
1663 g_assert(a->get || a->set);
1665 for (l = a->flags; l != NULL; l = l->next) {
1666 char *flag = l->data;
1668 if(strcmp (flag, "READABLE") == 0 ||
1669 strcmp (flag, "WRITABLE") == 0) {
1670 error_print(GOB_WARN, a->line_no,
1672 "WRITABLE argument flags are "
1673 "set automatically");
1676 for(i = 0; argflags[i]; i++) {
1677 if(strcmp(argflags[i], flag)==0)
1680 g_string_sprintfa(flags, " | %s%s", argflags[i] ? "G_PARAM_" : "", flag);
1683 g_string_append (flags, ")");
1685 s = g_strdup(a->name);
1687 if (!strcmp (a->gtktype, "ENUM"))
1688 out_printf(out, "\tparam_spec = g_param_spec_enum (\"%s\", NULL, NULL,\n"
1689 "\t\tG_TYPE_ENUM, 0,\n"
1691 a->name, flags->str);
1692 if (!strcmp (a->gtktype, "FLAGS"))
1693 out_printf(out, "\tparam_spec = g_param_spec_flags (\"%s\", NULL, NULL,\n"
1694 "\t\tG_TYPE_FLAGS, 0,\n"
1696 a->name, flags->str);
1697 else if (!strcmp (a->gtktype, "OBJECT"))
1698 out_printf(out, "\tparam_spec = g_param_spec_object (\"%s\", NULL, NULL,\n"
1699 "\t\tG_TYPE_OBJECT,\n"
1701 a->name, flags->str);
1702 else if (!strcmp (a->gtktype, "STRING"))
1703 out_printf(out, "\tparam_spec = g_param_spec_string (\"%s\", NULL, NULL,\n"
1706 a->name, flags->str);
1707 else if (!strcmp (a->gtktype, "INT"))
1708 out_printf(out, "\tparam_spec = g_param_spec_int (\"%s\", NULL, NULL,\n"
1709 "\t\tG_MININT, G_MAXINT,\n"
1712 a->name, flags->str);
1713 else if (!strcmp (a->gtktype, "UINT"))
1714 out_printf(out, "\tparam_spec = g_param_spec_uint (\"%s\", NULL, NULL,\n"
1715 "\t\t0, G_MAXUINT,\n"
1718 a->name, flags->str);
1719 else if (!strcmp (a->gtktype, "INT"))
1720 out_printf(out, "\tparam_spec = g_param_spec_int (\"%s\", NULL, NULL,\n"
1721 "\t\tG_MININT, G_MAXINT,\n"
1724 a->name, flags->str);
1725 else if (!strcmp (a->gtktype, "CHAR"))
1726 out_printf(out, "\tparam_spec = g_param_spec_char (\"%s\", NULL, NULL,\n"
1730 a->name, flags->str);
1731 else if (!strcmp (a->gtktype, "UCHAR"))
1732 out_printf(out, "\tparam_spec = g_param_spec_uchar (\"%s\", NULL, NULL,\n"
1736 a->name, flags->str);
1737 else if (!strcmp (a->gtktype, "BOOL") ||
1738 !strcmp (a->gtktype, "BOOLEAN"))
1739 out_printf(out, "\tparam_spec = g_param_spec_boolean (\"%s\", NULL, NULL,\n"
1742 a->name, flags->str);
1743 else if (!strcmp (a->gtktype, "LONG"))
1744 out_printf(out, "\tparam_spec = g_param_spec_long (\"%s\", NULL, NULL,\n"
1745 "\t\tG_MINLONG, G_MAXLONG,\n"
1748 a->name, flags->str);
1749 else if (!strcmp (a->gtktype, "ULONG"))
1750 out_printf(out, "\tparam_spec = g_param_spec_ulong (\"%s\", NULL, NULL,\n"
1751 "\t\t0, G_MAXULONG,\n"
1754 a->name, flags->str);
1755 else if (!strcmp (a->gtktype, "INT64"))
1756 out_printf(out, "\tparam_spec = g_param_spec_int64 (\"%s\", NULL, NULL,\n"
1757 "\t\tG_MININT64, G_MAXINT64,\n"
1760 a->name, flags->str);
1761 else if (!strcmp (a->gtktype, "UINT64"))
1762 out_printf(out, "\tparam_spec = g_param_spec_uint64 (\"%s\", NULL, NULL,\n"
1763 "\t\t0, G_MAXUINT64,\n"
1766 a->name, flags->str);
1767 else if (!strcmp (a->gtktype, "FLOAT"))
1768 out_printf(out, "\tparam_spec = g_param_spec_float (\"%s\", NULL, NULL,\n"
1769 "\t\t-G_MAXFLOAT, G_MAXFLOAT,\n"
1772 a->name, flags->str);
1773 else if (!strcmp (a->gtktype, "DOUBLE"))
1774 out_printf(out, "\tparam_spec = g_param_spec_double (\"%s\", NULL, NULL,\n"
1775 "\t\t-G_MAXDOUBLE, G_MAXDOUBLE,\n"
1778 a->name, flags->str);
1779 else if (!strcmp (a->gtktype, "POINTER"))
1780 out_printf(out, "\tparam_spec = g_param_spec_pointer (\"%s\", NULL, NULL,\n"
1782 a->name, flags->str);
1784 error_printf (GOB_ERROR, a->line_no,
1785 "%s type is not supported for arguments, try using properties",
1788 out_printf(out, "\tg_object_class_install_property (g_object_class,\n"
1789 "\t\tPROP_%s, param_spec);\n", s);
1793 g_string_free(flags, TRUE);
1796 #define value_for_print(str, alt) (str != NULL ? str : alt)
1799 make_property (Property *p)
1803 if (p->get == NULL && p->set == NULL) {
1804 error_print (GOB_ERROR, p->line_no,
1805 "Property has no getter nor setter");
1809 if (p->flags != NULL)
1810 error_print (GOB_WARN, p->line_no,
1811 "Overridden property, flags ignored");
1812 if (p->nick != NULL)
1813 error_print (GOB_WARN, p->line_no,
1814 "Overridden property, nick ignored");
1815 if (p->blurb != NULL)
1816 error_print (GOB_WARN, p->line_no,
1817 "Overridden property, blurb ignored");
1818 if (p->minimum != NULL)
1819 error_print (GOB_WARN, p->line_no,
1820 "Overridden property, minimum ignored");
1821 if (p->maximum != NULL)
1822 error_print (GOB_WARN, p->line_no,
1823 "Overridden property, maximum ignored");
1824 if (p->default_value != NULL)
1825 error_print (GOB_WARN, p->line_no,
1826 "Overridden property, default_value ignored");
1828 s = g_strdup (p->name);
1830 out_printf (out, "\tg_object_class_override_property (g_object_class,\n"
1832 "\t\t\"%s\");\n", s, value_for_print (p->canonical_name, p->name) );
1837 char *argflags[] = {
1845 flags = g_string_new ("(GParamFlags)(");
1847 if (p->get != NULL && p->set != NULL)
1848 g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
1849 else if (p->get != NULL)
1850 g_string_append (flags, "G_PARAM_READABLE");
1852 g_string_append (flags, "G_PARAM_WRITABLE");
1855 for (l = p->flags; l != NULL; l = l->next) {
1856 char *flag = l->data;
1858 if(strcmp (flag, "READABLE") == 0 ||
1859 strcmp (flag, "WRITABLE") == 0) {
1860 error_print(GOB_WARN, p->line_no,
1862 "WRITABLE argument flags are "
1863 "set automatically");
1866 for(i = 0; argflags[i]; i++) {
1867 if(strcmp(argflags[i], flag)==0)
1870 g_string_sprintfa(flags, " | %s%s", argflags[i] ? "G_PARAM_" : "", flag);
1873 g_string_append (flags, ")");
1875 if (strcmp (p->gtktype, "CHAR") == 0) {
1876 out_printf (out, "\tparam_spec = g_param_spec_char\n"
1877 "\t\t(\"%s\" /* name */,\n"
1878 "\t\t %s /* nick */,\n"
1879 "\t\t %s /* blurb */,\n"
1880 "\t\t %s /* minimum */,\n"
1881 "\t\t %s /* maximum */,\n"
1882 "\t\t %s /* default_value */,\n"
1884 value_for_print (p->canonical_name, p->name),
1885 value_for_print (p->nick, "NULL"),
1886 value_for_print (p->blurb, "NULL"),
1887 value_for_print (p->minimum, "-128"),
1888 value_for_print (p->maximum, "127"),
1889 value_for_print (p->default_value, "0"),
1891 } else if (strcmp (p->gtktype, "UCHAR") == 0) {
1892 out_printf (out, "\tparam_spec = g_param_spec_uchar\n"
1893 "\t\t(\"%s\" /* name */,\n"
1894 "\t\t %s /* nick */,\n"
1895 "\t\t %s /* blurb */,\n"
1896 "\t\t %s /* minimum */,\n"
1897 "\t\t %s /* maximum */,\n"
1898 "\t\t %s /* default_value */,\n"
1900 value_for_print (p->canonical_name, p->name),
1901 value_for_print (p->nick, "NULL"),
1902 value_for_print (p->blurb, "NULL"),
1903 value_for_print (p->minimum, "0"),
1904 value_for_print (p->maximum, "0xFF"),
1905 value_for_print (p->default_value, "0"),
1907 } else if (strcmp (p->gtktype, "BOOLEAN") == 0) {
1908 out_printf (out, "\tparam_spec = g_param_spec_boolean\n"
1909 "\t\t(\"%s\" /* name */,\n"
1910 "\t\t %s /* nick */,\n"
1911 "\t\t %s /* blurb */,\n"
1912 "\t\t %s /* default_value */,\n"
1914 value_for_print (p->canonical_name, p->name),
1915 value_for_print (p->nick, "NULL"),
1916 value_for_print (p->blurb, "NULL"),
1917 value_for_print (p->default_value, "FALSE"),
1919 } else if (strcmp (p->gtktype, "INT") == 0) {
1920 out_printf (out, "\tparam_spec = g_param_spec_int\n"
1921 "\t\t(\"%s\" /* name */,\n"
1922 "\t\t %s /* nick */,\n"
1923 "\t\t %s /* blurb */,\n"
1924 "\t\t %s /* minimum */,\n"
1925 "\t\t %s /* maximum */,\n"
1926 "\t\t %s /* default_value */,\n"
1928 value_for_print (p->canonical_name, p->name),
1929 value_for_print (p->nick, "NULL"),
1930 value_for_print (p->blurb, "NULL"),
1931 value_for_print (p->minimum, "G_MININT"),
1932 value_for_print (p->maximum, "G_MAXINT"),
1933 value_for_print (p->default_value, "0"),
1935 } else if (strcmp (p->gtktype, "UINT") == 0) {
1936 out_printf (out, "\tparam_spec = g_param_spec_uint\n"
1937 "\t\t(\"%s\" /* name */,\n"
1938 "\t\t %s /* nick */,\n"
1939 "\t\t %s /* blurb */,\n"
1940 "\t\t %s /* minimum */,\n"
1941 "\t\t %s /* maximum */,\n"
1942 "\t\t %s /* default_value */,\n"
1944 value_for_print (p->canonical_name, p->name),
1945 value_for_print (p->nick, "NULL"),
1946 value_for_print (p->blurb, "NULL"),
1947 value_for_print (p->minimum, "0"),
1948 value_for_print (p->maximum, "G_MAXUINT"),
1949 value_for_print (p->default_value, "0"),
1951 } else if (strcmp (p->gtktype, "LONG") == 0) {
1952 out_printf (out, "\tparam_spec = g_param_spec_long\n"
1953 "\t\t(\"%s\" /* name */,\n"
1954 "\t\t %s /* nick */,\n"
1955 "\t\t %s /* blurb */,\n"
1956 "\t\t %s /* minimum */,\n"
1957 "\t\t %s /* maximum */,\n"
1958 "\t\t %s /* default_value */,\n"
1960 value_for_print (p->canonical_name, p->name),
1961 value_for_print (p->nick, "NULL"),
1962 value_for_print (p->blurb, "NULL"),
1963 value_for_print (p->minimum, "G_MINLONG"),
1964 value_for_print (p->maximum, "G_MAXLONG"),
1965 value_for_print (p->default_value, "0"),
1967 } else if (strcmp (p->gtktype, "ULONG") == 0) {
1968 out_printf (out, "\tparam_spec = g_param_spec_ulong\n"
1969 "\t\t(\"%s\" /* name */,\n"
1970 "\t\t %s /* nick */,\n"
1971 "\t\t %s /* blurb */,\n"
1972 "\t\t %s /* minimum */,\n"
1973 "\t\t %s /* maximum */,\n"
1974 "\t\t %s /* default_value */,\n"
1976 value_for_print (p->canonical_name, p->name),
1977 value_for_print (p->nick, "NULL"),
1978 value_for_print (p->blurb, "NULL"),
1979 value_for_print (p->minimum, "0"),
1980 value_for_print (p->maximum, "G_MAXULONG"),
1981 value_for_print (p->default_value, "0"),
1983 } else if (strcmp (p->gtktype, "INT64") == 0) {
1984 out_printf (out, "\tparam_spec = g_param_spec_int64\n"
1985 "\t\t(\"%s\" /* name */,\n"
1986 "\t\t %s /* nick */,\n"
1987 "\t\t %s /* blurb */,\n"
1988 "\t\t %s /* minimum */,\n"
1989 "\t\t %s /* maximum */,\n"
1990 "\t\t %s /* default_value */,\n"
1992 value_for_print (p->canonical_name, p->name),
1993 value_for_print (p->nick, "NULL"),
1994 value_for_print (p->blurb, "NULL"),
1995 value_for_print (p->minimum, "G_MININT64"),
1996 value_for_print (p->maximum, "G_MAXINT64"),
1997 value_for_print (p->default_value, "0"),
1999 } else if (strcmp (p->gtktype, "UINT64") == 0) {
2000 out_printf (out, "\tparam_spec = g_param_spec_uint64\n"
2001 "\t\t(\"%s\" /* name */,\n"
2002 "\t\t %s /* nick */,\n"
2003 "\t\t %s /* blurb */,\n"
2004 "\t\t %s /* minimum */,\n"
2005 "\t\t %s /* maximum */,\n"
2006 "\t\t %s /* default_value */,\n"
2008 value_for_print (p->canonical_name, p->name),
2009 value_for_print (p->nick, "NULL"),
2010 value_for_print (p->blurb, "NULL"),
2011 value_for_print (p->minimum, "0"),
2012 value_for_print (p->maximum, "G_MAXUINT64"),
2013 value_for_print (p->default_value, "0"),
2015 } else if (strcmp (p->gtktype, "UNICHAR") == 0) {
2016 out_printf (out, "\tparam_spec = g_param_spec_unichar\n"
2017 "\t\t(\"%s\" /* name */,\n"
2018 "\t\t %s /* nick */,\n"
2019 "\t\t %s /* blurb */,\n"
2020 "\t\t %s /* default_value */,\n"
2022 value_for_print (p->canonical_name, p->name),
2023 value_for_print (p->nick, "NULL"),
2024 value_for_print (p->blurb, "NULL"),
2025 value_for_print (p->default_value, "0"),
2027 } else if (strcmp (p->gtktype, "ENUM") == 0) {
2028 char *type = make_me_type (p->extra_gtktype,
2030 out_printf (out, "\tparam_spec = g_param_spec_enum\n"
2031 "\t\t(\"%s\" /* name */,\n"
2032 "\t\t %s /* nick */,\n"
2033 "\t\t %s /* blurb */,\n"
2034 "\t\t %s /* enum_type */,\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"),
2041 value_for_print (p->default_value, "0"),
2044 } else if (strcmp (p->gtktype, "FLAGS") == 0) {
2045 char *type = make_me_type (p->extra_gtktype,
2047 out_printf (out, "\tparam_spec = g_param_spec_flags\n"
2048 "\t\t(\"%s\" /* name */,\n"
2049 "\t\t %s /* nick */,\n"
2050 "\t\t %s /* blurb */,\n"
2051 "\t\t %s /* flags_type */,\n"
2052 "\t\t %s /* default_value */,\n"
2054 value_for_print (p->canonical_name, p->name),
2055 value_for_print (p->nick, "NULL"),
2056 value_for_print (p->blurb, "NULL"),
2058 value_for_print (p->default_value, "0"),
2061 } else if (strcmp (p->gtktype, "FLOAT") == 0) {
2062 out_printf (out, "\tparam_spec = g_param_spec_float\n"
2063 "\t\t(\"%s\" /* name */,\n"
2064 "\t\t %s /* nick */,\n"
2065 "\t\t %s /* blurb */,\n"
2066 "\t\t %s /* minimum */,\n"
2067 "\t\t %s /* maximum */,\n"
2068 "\t\t %s /* default_value */,\n"
2070 value_for_print (p->canonical_name, p->name),
2071 value_for_print (p->nick, "NULL"),
2072 value_for_print (p->blurb, "NULL"),
2073 value_for_print (p->minimum, "-G_MAXFLOAT"),
2074 value_for_print (p->maximum, "G_MAXFLOAT"),
2075 value_for_print (p->default_value, "0.0"),
2077 } else if (strcmp (p->gtktype, "DOUBLE") == 0) {
2078 out_printf (out, "\tparam_spec = g_param_spec_double\n"
2079 "\t\t(\"%s\" /* name */,\n"
2080 "\t\t %s /* nick */,\n"
2081 "\t\t %s /* blurb */,\n"
2082 "\t\t %s /* minimum */,\n"
2083 "\t\t %s /* maximum */,\n"
2084 "\t\t %s /* default_value */,\n"
2086 value_for_print (p->canonical_name, p->name),
2087 value_for_print (p->nick, "NULL"),
2088 value_for_print (p->blurb, "NULL"),
2089 value_for_print (p->minimum, "-G_MAXDOUBLE"),
2090 value_for_print (p->maximum, "G_MAXDOUBLE"),
2091 value_for_print (p->default_value, "0.0"),
2093 } else if (strcmp (p->gtktype, "STRING") == 0) {
2094 out_printf (out, "\tparam_spec = g_param_spec_string\n"
2095 "\t\t(\"%s\" /* name */,\n"
2096 "\t\t %s /* nick */,\n"
2097 "\t\t %s /* blurb */,\n"
2098 "\t\t %s /* default_value */,\n"
2100 value_for_print (p->canonical_name, p->name),
2101 value_for_print (p->nick, "NULL"),
2102 value_for_print (p->blurb, "NULL"),
2103 value_for_print (p->default_value, "NULL"),
2105 } else if (strcmp (p->gtktype, "PARAM") == 0) {
2106 char *type = make_me_type (p->extra_gtktype,
2108 out_printf (out, "\tparam_spec = g_param_spec_param\n"
2109 "\t\t(\"%s\" /* name */,\n"
2110 "\t\t %s /* nick */,\n"
2111 "\t\t %s /* blurb */,\n"
2112 "\t\t %s /* param_type */,\n"
2114 value_for_print (p->canonical_name, p->name),
2115 value_for_print (p->nick, "NULL"),
2116 value_for_print (p->blurb, "NULL"),
2120 } else if (strcmp (p->gtktype, "BOXED") == 0) {
2121 char *type = make_me_type (p->extra_gtktype,
2123 out_printf (out, "\tparam_spec = g_param_spec_boxed\n"
2124 "\t\t(\"%s\" /* name */,\n"
2125 "\t\t %s /* nick */,\n"
2126 "\t\t %s /* blurb */,\n"
2127 "\t\t %s /* boxed_type */,\n"
2129 value_for_print (p->canonical_name, p->name),
2130 value_for_print (p->nick, "NULL"),
2131 value_for_print (p->blurb, "NULL"),
2135 } else if (strcmp (p->gtktype, "POINTER") == 0) {
2136 out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
2137 "\t\t(\"%s\" /* name */,\n"
2138 "\t\t %s /* nick */,\n"
2139 "\t\t %s /* blurb */,\n"
2141 value_for_print (p->canonical_name, p->name),
2142 value_for_print (p->nick, "NULL"),
2143 value_for_print (p->blurb, "NULL"),
2145 /* FIXME: VALUE_ARRAY */
2146 } else if (strcmp (p->gtktype, "CLOSURE") == 0) {
2147 out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
2148 "\t\t(\"%s\" /* name */,\n"
2149 "\t\t %s /* nick */,\n"
2150 "\t\t %s /* blurb */,\n"
2152 value_for_print (p->canonical_name, p->name),
2153 value_for_print (p->nick, "NULL"),
2154 value_for_print (p->blurb, "NULL"),
2156 } else if (strcmp (p->gtktype, "OBJECT") == 0) {
2157 char *type = make_me_type (p->extra_gtktype,
2159 out_printf (out, "\tparam_spec = g_param_spec_object\n"
2160 "\t\t(\"%s\" /* name */,\n"
2161 "\t\t %s /* nick */,\n"
2162 "\t\t %s /* blurb */,\n"
2163 "\t\t %s /* object_type */,\n"
2165 value_for_print (p->canonical_name, p->name),
2166 value_for_print (p->nick, "NULL"),
2167 value_for_print (p->blurb, "NULL"),
2172 error_printf (GOB_ERROR, p->line_no,
2173 "%s type is not supported by properties",
2177 s = g_strdup (p->name);
2179 out_printf (out, "\tg_object_class_install_property (g_object_class,\n"
2181 "\t\tparam_spec);\n", s);
2184 g_string_free (flags, TRUE);
2189 make_arguments(Class *c)
2192 if (get_properties > 0)
2193 out_printf(out, "\tg_object_class->get_property = ___object_get_property;\n");
2194 if (set_properties > 0)
2195 out_printf(out, "\tg_object_class->set_property = ___object_set_property;\n");
2196 out_printf (out, " {\n");
2197 for (li = c->nodes; li != NULL; li = li->next) {
2199 if ((n->type == PROPERTY_NODE && ! ((Property *) n)->override)
2200 || n->type == ARGUMENT_NODE) {
2201 out_printf(out, "\tGParamSpec *param_spec;\n\n");
2206 for (li = c->nodes; li != NULL; li = li->next) {
2208 if (n->type == PROPERTY_NODE)
2209 make_property ((Property *)n);
2210 else if (n->type == ARGUMENT_NODE)
2211 make_argument ((Argument *)n);
2213 out_printf(out, " }\n");
2217 print_initializer(Method *m, Variable *v)
2224 if(v->initializer == NULL)
2227 if(v->scope == PRIVATE_SCOPE)
2228 root = g_strconcat(((FuncArg *)m->args->data)->name,
2231 root = g_strdup(((FuncArg *)m->args->data)->name);
2233 if(v->initializer_line > 0)
2234 out_addline_infile(out, v->initializer_line);
2236 if (v->initializer_simple)
2237 out_printf(out, "\t%s->%s = %s;\n",
2238 root, v->id, v->initializer);
2239 else if (strcmp(v->id, "_glade_xml") == 0)
2240 /* This is OK, this v->initializer string is set internally
2241 and it will eat exactly one string! */
2242 out_printf(out,v->initializer, ((FuncArg *)m->args->data)->name);
2244 out_printf(out, "%s", v->initializer);
2246 if(v->initializer_line > 0)
2247 out_addline_outfile(out);
2253 print_glade_widget(Method *m, Variable *v)
2258 if(!v->glade_widget)
2261 if(v->scope == PRIVATE_SCOPE)
2262 root = g_strconcat(((FuncArg *)m->args->data)->name,
2265 root = g_strdup(((FuncArg *)m->args->data)->name);
2267 cast = get_type(v->vtype, FALSE);
2268 out_printf(out, "\t%s->%s = (%s)glade_xml_get_widget(%s->_glade_xml, \"%s\");\n",
2269 root, v->id, cast, root, v->id);
2275 print_destructor (Variable *v)
2279 if(v->destructor == NULL)
2282 if(v->scope == PRIVATE_SCOPE)
2283 root = "self->_priv";
2287 if(v->destructor_simple) {
2288 if(v->destructor_line > 0)
2289 out_addline_infile(out, v->destructor_line);
2292 out_printf(out, "\tif(%s->%s) { "
2293 "(reinterpret_cast<void (*)(void *)>(%s)) ((gpointer)%s->%s); "
2294 "%s->%s = NULL; }\n",
2295 root, v->id, v->destructor, root, v->id,
2298 out_printf(out, "\tif(%s->%s) { "
2299 "%s ((gpointer) %s->%s); "
2300 "%s->%s = NULL; }\n",
2301 root, v->id, v->destructor, root, v->id,
2305 if(v->destructor_line > 0)
2306 out_addline_outfile(out);
2308 out_printf(out, "#define %s (%s->%s)\n", v->id, root, v->id);
2309 out_printf(out, "#define VAR %s\n", v->id);
2310 out_printf(out, "\t{\n");
2311 if(v->destructor_line > 0)
2312 out_addline_infile(out, v->destructor_line);
2314 out_printf(out, "\t%s}\n", v->destructor);
2316 if(v->destructor_line > 0)
2317 out_addline_outfile(out);
2318 out_printf(out, "\tmemset(&(%s), 0, sizeof(%s));\n",
2320 out_printf(out, "#undef VAR\n");
2321 out_printf(out, "#undef %s\n", v->id);
2326 add_constructor (Class *c)
2328 out_printf(out, "\nstatic GObject *\n"
2329 "___constructor (GType type, guint n_construct_properties, GObjectConstructParam *construct_properties)\n"
2332 "#define __GOB_FUNCTION__ \"%s::constructor\"\n",
2335 out_printf(out, "\tGObject *obj_self;\n");
2336 out_printf(out, "\t%s *self;\n", typebase);
2338 out_printf(out, "\tobj_self = G_OBJECT_CLASS (parent_class)->constructor (type, n_construct_properties, construct_properties);\n");
2339 out_printf(out, "\tself = %s (obj_self);\n", macrobase);
2341 if (user_constructor->line_no > 0)
2342 out_addline_infile (out, user_constructor->line_no);
2343 out_printf (out, "\t%s_constructor (self);\n", funcbase);
2344 if (user_constructor->line_no > 0)
2345 out_addline_outfile (out);
2347 out_printf(out, "\treturn obj_self;\n");
2348 out_printf(out, "}\n"
2349 "#undef __GOB_FUNCTION__\n\n");
2353 print_unreftors (Class *c)
2356 for(li = ((Class *)class)->nodes;
2360 Variable *v = (Variable *)n;
2361 if (n->type == VARIABLE_NODE &&
2362 v->scope != CLASS_SCOPE &&
2363 v->destructor_unref)
2364 print_destructor (v);
2369 add_dispose (Class *c)
2371 out_printf(out, "\nstatic void\n"
2372 "___dispose (GObject *obj_self)\n"
2375 "#define __GOB_FUNCTION__ \"%s::dispose\"\n",
2378 if (unreftors > 0 || user_dispose_method != NULL) {
2379 out_printf (out, "\t%s *self%s = %s (obj_self);\n",
2381 ! no_gnu ? " G_GNUC_UNUSED" : "",
2385 if (dispose_handler != NULL) {
2386 if (unreftors > 0) {
2387 print_unreftors (c);
2390 /* so we get possible bad argument warning */
2391 if (dispose_handler->line_no > 0)
2392 out_addline_infile (out, dispose_handler->line_no);
2393 out_printf (out, "\t___%x_%s_dispose(obj_self);\n",
2394 (guint)dispose_handler->unique_id, funcbase);
2395 if (dispose_handler->line_no > 0)
2396 out_addline_outfile (out);
2398 if (user_dispose_method != NULL) {
2399 if (user_dispose_method->line_no > 0)
2400 out_addline_infile (out, user_dispose_method->line_no);
2401 out_printf (out, "\t%s_dispose (self);\n", funcbase);
2402 if (user_dispose_method->line_no > 0)
2403 out_addline_outfile (out);
2406 if (unreftors > 0) {
2407 print_unreftors (c);
2411 "\tif (G_OBJECT_CLASS (parent_class)->dispose) \\\n"
2412 "\t\t(* G_OBJECT_CLASS (parent_class)->dispose) (obj_self);\n");
2415 out_printf(out, "}\n"
2416 "#undef __GOB_FUNCTION__\n\n");
2420 print_destructors (Class *c)
2423 for (li = ((Class *)class)->nodes;
2427 Variable *v = (Variable *)n;
2428 if (n->type == VARIABLE_NODE &&
2429 v->scope != CLASS_SCOPE &&
2430 ! v->destructor_unref)
2431 print_destructor (v);
2436 add_finalize (Class *c)
2440 "___finalize(GObject *obj_self)\n"
2443 "#define __GOB_FUNCTION__ \"%s::finalize\"\n",
2448 user_finalize_method != NULL) {
2449 const char *unused = "";
2451 unused = " G_GNUC_UNUSED";
2452 out_printf(out, "\t%s *self%s = %s (obj_self);\n",
2453 typebase, unused, macrobase);
2456 const char *unused = "";
2458 unused = " G_GNUC_UNUSED";
2459 out_printf(out, "\tgpointer priv%s = self->_priv;\n",
2463 if(finalize_handler) {
2464 if (destructors > 0) {
2465 print_destructors (c);
2468 /* so we get possible bad argument warning */
2469 if(finalize_handler->line_no > 0)
2470 out_addline_infile(out, finalize_handler->line_no);
2471 out_printf(out, "\t___%x_%s_finalize(obj_self);\n",
2472 (guint)finalize_handler->unique_id, funcbase);
2473 if(finalize_handler->line_no > 0)
2474 out_addline_outfile(out);
2476 if (user_finalize_method != NULL) {
2477 if (user_finalize_method->line_no > 0)
2478 out_addline_infile (out, user_finalize_method->line_no);
2479 out_printf (out, "\t%s_finalize (self);\n", funcbase);
2480 if (user_finalize_method->line_no > 0)
2481 out_addline_outfile (out);
2484 if (destructors > 0) {
2485 print_destructors (c);
2489 "\tif(G_OBJECT_CLASS(parent_class)->finalize) \\\n"
2490 "\t\t(* G_OBJECT_CLASS(parent_class)->finalize)(obj_self);\n");
2493 out_printf(out, "}\n"
2494 "#undef __GOB_FUNCTION__\n\n");
2498 make_bonobo_object_epv (Class *c, const char *classname)
2501 gboolean added_line = FALSE;
2503 for (li = c->nodes; li != NULL; li = li->next) {
2505 Method *m = (Method *)n;
2506 if(n->type != METHOD_NODE ||
2507 m->method == OVERRIDE_METHOD)
2510 if (m->bonobo_object_func) {
2511 if(m->line_no > 0) {
2512 out_addline_infile(out, m->line_no);
2514 } else if (m->line_no == 0 &&
2516 out_addline_outfile(out);
2519 out_printf (out, "\t%s->_epv.%s = self_%s;\n",
2520 classname, m->id, m->id);
2524 out_addline_outfile(out);
2530 const char *unused = "";
2534 unused = " G_GNUC_UNUSED";
2536 for(li=c->nodes;li;li=g_list_next(li)) {
2540 if(n->type != METHOD_NODE)
2543 if(m->method == INIT_METHOD) {
2545 out_addline_infile(out, m->line_no);
2546 print_method(out, "static ", "\n", "", " ", "", "\n",
2547 m, FALSE, FALSE, FALSE, TRUE, TRUE,
2549 out_printf(out, "{\n");
2551 out_addline_outfile(out);
2553 "#define __GOB_FUNCTION__ \"%s::init\"\n",
2556 out_printf(out, "\t%s->_priv = "
2557 "G_TYPE_INSTANCE_GET_PRIVATE(%s,%s,%sPrivate);\n",
2558 ((FuncArg *)m->args->data)->name,
2559 ((FuncArg *)m->args->data)->name,
2562 } else if(always_private_struct) {
2563 out_printf(out, "\t%s->_priv = NULL;\n",
2564 ((FuncArg *)m->args->data)->name);
2566 if(initializers > 0) {
2568 for(li = ((Class *)class)->nodes;
2572 Variable *v = (Variable *)n;
2573 if(n->type != VARIABLE_NODE ||
2574 v->scope == CLASS_SCOPE)
2576 print_initializer(m, v);
2579 if(glade_widgets > 0) {
2581 for(li = ((Class *)class)->nodes;
2585 Variable *v = (Variable *)n;
2586 if(n->type != VARIABLE_NODE ||
2587 v->scope == CLASS_SCOPE)
2589 print_glade_widget(m, v);
2592 } else if(m->method == CLASS_INIT_METHOD) {
2593 gboolean did_base_obj = FALSE;
2596 out_addline_infile(out, m->line_no);
2597 print_method(out, "static ", "\n", "", " ", "", "\n",
2598 m, FALSE, FALSE, FALSE, TRUE, TRUE,
2600 out_printf(out, "{\n");
2602 out_addline_outfile(out);
2604 "#define __GOB_FUNCTION__ \"%s::class_init\"\n",
2606 if (set_properties > 0 ||
2607 get_properties > 0 ||
2614 "g_object_class%s = "
2615 "(GObjectClass*) %s;\n",
2617 ((FuncArg *)m->args->data)->name);
2618 did_base_obj = TRUE;
2623 ((FuncArg *)m->args->data)->name,
2628 "\n\tg_type_class_add_private(%s,sizeof(%sPrivate));\n",
2629 ((FuncArg *)m->args->data)->name,
2632 if (initializers > 0) {
2634 for(li = ((Class *)class)->nodes;
2638 Variable *v = (Variable *)n;
2639 if(n->type == VARIABLE_NODE &&
2640 v->scope == CLASS_SCOPE)
2641 print_initializer(m, v);
2645 out_printf(out, "\n\tparent_class = ");
2647 out_printf(out, "(%sClass *)", ptypebase);
2648 out_printf(out, "g_type_class_ref (%s);\n",
2654 set_def_handlers(c, ((FuncArg *)m->args->data)->name);
2656 /* if there are no handlers for these things, we
2657 * need to set them up here */
2658 if(need_constructor)
2659 out_printf(out, "\tg_object_class->constructor "
2660 "= ___constructor;\n");
2661 if(need_dispose && !dispose_handler)
2662 out_printf(out, "\tg_object_class->dispose "
2664 if(need_finalize && !finalize_handler)
2665 out_printf(out, "\tg_object_class->finalize = "
2668 if(get_properties > 0 || set_properties > 0)
2671 if (c->bonobo_object_class != NULL) {
2672 make_bonobo_object_epv (c, ((FuncArg *)m->args->data)->name);
2678 out_printf(out, " {\n");
2679 out_addline_infile(out, m->ccode_line);
2680 out_printf(out, "%s\n", m->cbuf);
2681 out_addline_outfile(out);
2682 out_printf(out, " }\n");
2684 out_printf(out, "}\n"
2685 "#undef __GOB_FUNCTION__\n");
2690 add_argument (Argument *a, gboolean is_set)
2694 char *the_type_lower;
2699 line_no = a->set_line;
2702 line_no = a->get_line;
2706 s = g_strdup(a->name);
2708 out_printf(out, "\tcase PROP_%s:\n\t{", s);
2710 the_type_lower = g_strdup (a->gtktype);
2711 gob_strdown (the_type_lower);
2713 /* HACK because there is no g_value_set/get for unichar */
2714 if (strcmp (the_type_lower, "unichar") == 0) {
2715 g_free (the_type_lower);
2716 the_type_lower = g_strdup ("uint");
2721 const char *unused = "";
2723 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
2724 unused = " G_GNUC_UNUSED";
2727 if (a->atype != NULL &&
2728 /* gcc -Wbad-function-cast is wanking stupid, moronic
2729 and otherwise evil so we should just use a (gint)
2730 or (guint) cast, not the specific type cast */
2732 (strcmp (a->gtktype, "ENUM") != 0 &&
2733 strcmp (a->gtktype, "FLAGS") != 0)))
2734 cast = get_type (a->atype, TRUE);
2736 cast = g_strdup (get_cast (a->gtktype, FALSE));
2738 out_printf (out, "\t%s ARG%s = (%s) g_value_get_%s (VAL);\n",
2739 cast, unused, cast, the_type_lower);
2742 } else if ( ! is_set) {
2745 if (a->atype != NULL)
2746 cast = get_type (a->atype, TRUE);
2748 cast = g_strdup (get_cast (a->gtktype, FALSE));
2749 out_printf (out, "\t%s ARG;\n"
2750 "\tmemset (&ARG, 0, sizeof (%s));\n",
2756 out_printf(out, "\t\t{\n");
2758 out_addline_infile (out, line_no);
2759 out_printf (out, "%s\n", cbuf);
2761 out_addline_outfile (out);
2762 out_printf (out, "\t\t}\n");
2764 if (strcmp (a->gtktype, "OBJECT") == 0)
2765 out_printf (out, "\t\tg_value_set_%s (VAL, G_OBJECT (ARG));\n",
2768 out_printf (out, "\t\t"
2769 "g_value_set_%s (VAL, ARG);\n",
2772 g_free (the_type_lower);
2775 (no_gnu || for_cpp /* g++ has a cow with G_GNUC_UNUSED */)) {
2776 out_printf (out, "\t\tif (&ARG) break;\n");
2779 out_printf (out, "\t\tbreak;\n");
2781 out_printf (out, "\t}\n");
2785 add_property (Property *p, gboolean is_set)
2788 char *the_type_lower;
2794 line_no = p->set_line;
2797 line_no = p->get_line;
2802 name_upper = g_strdup (p->name);
2803 gob_strup (name_upper);
2804 the_type_lower = g_strdup (p->gtktype);
2805 gob_strdown (the_type_lower);
2807 out_printf (out, "\tcase PROP_%s:\n", name_upper);
2809 out_printf(out, "\t\t{\n");
2811 out_addline_infile (out, line_no);
2812 out_printf (out, "%s\n", cbuf);
2814 out_addline_outfile (out);
2815 out_printf (out, "\t\t}\n");
2817 g_free (name_upper);
2818 g_free (the_type_lower);
2820 out_printf (out, "\t\tbreak;\n");
2824 add_getset_arg(Class *c, gboolean is_set)
2827 const char *unused = "";
2828 const char *hack_unused = "";
2830 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
2831 unused = " G_GNUC_UNUSED";
2833 hack_unused = "if (&VAL || &pspec) break;\n\t\t";
2836 out_printf(out, "\nstatic void\n"
2837 "___object_%s_property (GObject *object,\n"
2838 "\tguint property_id,\n"
2839 "\t%sGValue *VAL%s,\n"
2840 "\tGParamSpec *pspec%s)\n"
2841 "#define __GOB_FUNCTION__ \"%s::%s_property\"\n"
2844 "\tself = %s (object);\n\n"
2845 "\tswitch (property_id) {\n",
2846 is_set ? "set" : "get",
2847 is_set ? "const " : "",
2851 is_set ? "set" : "get",
2856 for (li = c->nodes; li != NULL; li = li->next) {
2858 if (n->type == PROPERTY_NODE)
2859 add_property ((Property *)n, is_set);
2860 else if (n->type == ARGUMENT_NODE)
2861 add_argument ((Argument *)n, is_set);
2863 out_printf (out, "\tdefault:\n"
2864 "/* Apparently in g++ this is needed, glib is b0rk */\n"
2865 "#ifndef __PRETTY_FUNCTION__\n"
2866 "# undef G_STRLOC\n"
2867 "# define G_STRLOC __FILE__ \":\" G_STRINGIFY (__LINE__)\n"
2869 "\t\tG_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);\n"
2870 "\t\t%sbreak;\n\t}\n"
2872 "#undef __GOB_FUNCTION__\n", hack_unused);
2876 print_checks (Method *m, FuncArg *fa)
2880 gboolean checked_null = FALSE;
2881 is_void = (strcmp(m->mtype->name, "void")==0 &&
2882 m->mtype->pointer == NULL);
2884 for(li = fa->checks; li != NULL; li = li->next) {
2885 Check *ch = li->data;
2887 /* point to the method prot in .gob for failed checks */
2889 out_addline_infile(out, m->line_no);
2891 out_printf(out, "\tg_return_if_fail (");
2893 out_printf(out, "\tg_return_val_if_fail (");
2894 switch(ch->chtype) {
2896 out_printf(out, "%s != NULL", fa->name);
2897 checked_null = TRUE;
2900 s = make_pre_macro(fa->atype->name, "IS");
2902 out_printf(out, "%s (%s)", s, fa->name);
2904 /* if not check null, null may be valid */
2905 out_printf(out, "!(%s) || %s (%s)", fa->name,
2910 out_printf(out, "%s < %s", fa->name, ch->number);
2913 out_printf(out, "%s > %s", fa->name, ch->number);
2916 out_printf(out, "%s <= %s", fa->name, ch->number);
2919 out_printf(out, "%s >= %s", fa->name, ch->number);
2922 out_printf(out, "%s == %s", fa->name, ch->number);
2925 out_printf(out, "%s != %s", fa->name, ch->number);
2929 out_printf(out, ");\n");
2931 out_printf(out, ", (");
2932 print_type(out, m->mtype, TRUE);
2933 out_printf(out, ")%s);\n",
2934 m->onerror?m->onerror:"0");
2940 print_preconditions(Method *m)
2944 for(li=m->args;li;li=g_list_next(li)) {
2945 FuncArg *fa = li->data;
2947 print_checks(m, fa);
2950 out_addline_outfile(out);
2954 print_method_body (Method *m, gboolean pre, gboolean unused_self)
2956 out_printf(out, "{\n");
2958 out_addline_outfile(out);
2959 out_printf(out, "#define __GOB_FUNCTION__ \"%s::%s\"\n",
2960 ((Class *)class)->otype,
2963 print_preconditions(m);
2967 (no_gnu || for_cpp) &&
2969 ((FuncArg *)(m->args->data))->name != NULL &&
2970 strcmp (((FuncArg *)(m->args->data))->name, "self") == 0) {
2971 out_printf (out, "\tif (&self) { ; }\n");
2974 /* Note: the trailing }'s are on one line, this is so
2975 that we get the no return warning correctly and point to
2976 the correct line in the .gob file, yes this is slightly
2977 ugly in the .c file, but that is not supposed to be
2978 human readable anyway. */
2980 out_printf(out, "{\n");
2982 out_addline_infile(out, m->ccode_line);
2983 out_printf(out, "\t%s}", m->cbuf);
2986 /* Note, there is no \n between the last } and this } so that
2987 * errors/warnings reported on the end of the body get pointed to the
2988 * right line in the .gob source */
2989 out_printf(out, "}\n");
2992 out_addline_outfile(out);
2993 out_printf(out, "#undef __GOB_FUNCTION__\n");
2997 put_signal_args (Method *m)
3003 if (m->args->next == NULL)
3006 for (ali = m->gtktypes->next, li = m->args->next, i = 1;
3007 li != NULL && ali != NULL;
3008 li = li->next, ali = ali->next, i++) {
3009 FuncArg *fa = li->data;
3010 char *str = ali->data;
3011 char *cast = g_strdup (get_cast (str, FALSE));
3012 /* FIXME: This code is so fucking ugly it hurts */
3013 gboolean do_static =
3014 (strcmp (str, "STRING") == 0 ||
3015 strcmp (str, "BOXED") == 0 ||
3016 strncmp (str, "BOXED_", 6) == 0);
3021 cast = get_type (fa->atype, TRUE);
3023 /* we should have already proved before that
3024 the we know all the types */
3025 g_assert (cast != NULL);
3027 if (strncmp (str, "BOXED_", 6) == 0)
3028 t = g_strdup (&(str[6]));
3030 t = g_strconcat ("G_TYPE_", str, NULL);
3033 "\t___param_values[%d].g_type = 0;\n"
3034 "\tg_value_init (&___param_values[%d], %s);\n",
3038 if (strcmp (str, "UNICHAR") == 0)
3039 /* hack because glib is braindamaged */
3040 set_func = g_strdup ("g_value_set_uint");
3041 else if (strncmp (str, "BOXED_", 6) == 0)
3042 set_func = g_strdup ("g_value_set_static_boxed");
3044 set_func = g_strdup_printf ("g_value_set%s_%s",
3045 do_static ? "_static" : "",
3047 gob_strdown (set_func);
3049 out_printf (out, "\t%s (&___param_values[%d], (%s) %s);\n\n",
3050 set_func, i, cast, fa->name);
3058 clear_signal_args (Method *m)
3063 out_printf (out, "\n\tg_value_unset (&___param_values[0]);\n");
3065 if (m->args->next == NULL)
3068 for (li = m->args->next, i = 1;
3070 li = li->next, i++) {
3072 "\tg_value_unset (&___param_values[%d]);\n", i);
3077 get_arg_names_for_macro (Method *m)
3081 GString *gs = g_string_new(NULL);
3083 for(li=m->args;li;li=g_list_next(li)) {
3084 FuncArg *arg = li->data;
3085 g_string_sprintfa (gs, "%s___%s", sep, arg->name);
3088 return g_string_free (gs, FALSE);
3091 static gboolean method_is_void(Method *m)
3093 return !strcmp(m->mtype->name, "void") && !m->mtype->pointer;
3096 static const char *method_err_retval(Method *m)
3098 if (method_is_void(m))
3106 put_interface_parent_handler(Method *m)
3108 const char *errval = method_err_retval(m);
3109 char *name = replace_sep(m->interface, '_');
3110 char *args = get_arg_names_for_macro(m);
3112 out_printf(out, "#define PARENT_HANDLER(%s) (%s_parent_iface \\\n"
3113 "\t? %s_parent_iface->%s(%s) \\\n"
3114 "\t: %s)\n", args, name, name, m->id, args, errval);
3121 put_method(Method *m)
3123 char *s, *args, *doc;
3125 is_void = (strcmp(m->mtype->name, "void")==0 &&
3126 m->mtype->pointer == NULL);
3127 out_printf(out, "\n");
3128 if(m->method != OVERRIDE_METHOD) {
3129 doc = get_gtk_doc(m->id);
3131 out_printf(out, "%s", doc);
3137 case REGULAR_METHOD:
3139 out_addline_infile(out, m->line_no);
3140 if(m->scope == PRIVATE_SCOPE)
3141 print_method(out, "static ", "\n", "", " ", "", "\n",
3142 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3143 else /* PUBLIC, PROTECTED */
3144 print_method(out, "", "\n", "", " ", "", "\n",
3145 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3148 out_addline_outfile(out);
3149 put_interface_parent_handler(m);
3152 print_method_body(m, TRUE, TRUE);
3155 out_printf(out, "#undef PARENT_HANDLER\n");
3158 /* the outfile line was added above */
3160 case SIGNAL_FIRST_METHOD:
3161 case SIGNAL_LAST_METHOD:
3163 out_addline_infile(out, m->line_no);
3164 if(m->scope == PRIVATE_SCOPE)
3165 print_method(out, "static ", "\n", "", " ", "", "\n",
3166 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3167 else /* PUBLIC, PROTECTED */
3168 print_method(out, "", "\n", "", " ", "", "\n",
3169 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3170 out_printf (out, "{\n");
3172 out_addline_outfile (out);
3175 "\tGValue ___param_values[%d];\n"
3176 "\tGValue ___return_val;\n\n"
3177 "memset (&___return_val, 0, "
3178 "sizeof (___return_val));\n"
3179 "memset (&___param_values, 0, "
3180 "sizeof (___param_values));\n\n",
3181 g_list_length (m->args));
3183 print_preconditions (m);
3186 "\n\t___param_values[0].g_type = 0;\n"
3187 "\tg_value_init (&___param_values[0], G_TYPE_FROM_INSTANCE (%s));\n"
3188 "\tg_value_set_instance (&___param_values[0], (gpointer) %s);\n\n",
3189 ((FuncArg *)m->args->data)->name,
3190 ((FuncArg *)m->args->data)->name);
3192 put_signal_args (m);
3194 if (strcmp (m->gtktypes->data, "NONE") != 0) {
3195 const char *defret = NULL;
3197 out_printf (out, "\tg_value_init (&___return_val, G_TYPE_%s);\n",
3198 (char *)m->gtktypes->data);
3200 if (m->defreturn != NULL)
3201 defret = m->defreturn;
3202 else if (m->onerror != NULL)
3203 defret = m->onerror;
3205 if (defret != NULL) {
3207 /* FIXME: This code is so fucking ugly it hurts */
3208 gboolean do_static =
3209 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
3210 strcmp ((char *)m->gtktypes->data, "BOXED") == 0);
3211 char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
3213 cast = get_type (m->mtype, TRUE);
3215 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
3216 /* hack because glib is braindamaged */
3217 set_func = g_strdup ("g_value_set_uint");
3219 set_func = g_strdup_printf ("g_value_set%s_%s",
3220 do_static ? "_static" : "",
3221 (char *)m->gtktypes->data);
3222 gob_strdown (set_func);
3224 out_printf (out, "\t%s (&___return_val, (%s) (%s));\n",
3225 set_func, cast, defret);
3230 out_printf (out, "\n");
3233 s = g_strdup (m->id);
3236 out_printf(out, "\tg_signal_emitv (___param_values,\n"
3237 "\t\tobject_signals[%s_SIGNAL],\n"
3238 "\t\t0 /* detail */,\n"
3239 "\t\t&___return_val);\n", s);
3243 clear_signal_args (m);
3245 if (strcmp (m->gtktypes->data, "NONE") != 0) {
3246 char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
3248 /* Hack because glib is very very braindead */
3250 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
3251 strcmp ((char *)m->gtktypes->data, "BOXED") == 0 ||
3252 strcmp ((char *)m->gtktypes->data, "OBJECT") == 0 ||
3253 strcmp ((char *)m->gtktypes->data, "PARAM") == 0);
3255 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
3256 /* hack because glib is braindamaged */
3257 getfunc = g_strdup ("g_value_get_uint");
3259 getfunc = g_strdup_printf ("g_value_%s_%s",
3260 do_dup ? "dup" : "get",
3261 (char *)m->gtktypes->data);
3262 gob_strdown (getfunc);
3265 cast = get_type (m->mtype, TRUE);
3270 print_type (out, m->mtype, TRUE);
3272 " ___ret = (%s) %s (&___return_val);\n"
3273 "\t\tg_value_unset (&___return_val);\n"
3274 "\t\treturn ___ret;\n"
3281 out_printf(out, "}\n");
3286 out_addline_infile(out, m->line_no);
3287 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
3288 m, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE);
3289 print_method_body(m, FALSE, TRUE);
3290 /* the outfile line was added above */
3292 case VIRTUAL_METHOD:
3294 out_addline_infile(out, m->line_no);
3295 if(m->scope==PRIVATE_SCOPE)
3296 print_method(out, "static ", "\n", "", " ", "", "\n",
3297 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3298 else /* PUBLIC, PROTECTED */
3299 print_method(out, "", "\n", "", " ", "", "\n",
3300 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3301 out_printf(out, "{\n");
3302 out_addline_outfile(out);
3303 out_printf(out, "\t%sClass *klass;\n", typebase);
3304 print_preconditions(m);
3305 out_printf(out, "\tklass = %s_GET_CLASS(%s);\n\n"
3306 "\tif(klass->%s)\n",
3307 macrobase, ((FuncArg *)m->args->data)->name,
3309 if(strcmp(m->mtype->name, "void") == 0 &&
3310 m->mtype->pointer == NULL) {
3312 out_printf(out, "\t\t(*klass->%s)(%s",
3314 ((FuncArg *)m->args->data)->name);
3315 for(li=m->args->next;li;li=g_list_next(li)) {
3316 FuncArg *fa = li->data;
3317 out_printf(out, ",%s", fa->name);
3319 out_printf(out, ");\n}\n");
3322 out_printf(out, "\t\treturn (*klass->%s)(%s",
3324 ((FuncArg *)m->args->data)->name);
3325 for(li=m->args->next;li;li=g_list_next(li)) {
3326 FuncArg *fa = li->data;
3327 out_printf(out, ",%s", fa->name);
3329 out_printf(out, ");\n"
3332 print_type(out, m->mtype, TRUE);
3334 out_printf(out, ")(%s);\n}\n", m->defreturn);
3336 out_printf(out, ")(%s);\n}\n", m->onerror);
3338 out_printf(out, ")(0);\n}\n");
3344 out_addline_infile(out, m->line_no);
3345 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
3346 m, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE);
3347 print_method_body(m, FALSE, TRUE);
3348 /* the outfile line was added above */
3350 case OVERRIDE_METHOD:
3354 out_addline_infile(out, m->line_no);
3355 s = g_strdup_printf("\n___%x_", (guint)m->unique_id);
3356 print_method(out, "static ", s, "", " ", "", "\n",
3357 m, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE);
3359 out_addline_outfile(out);
3360 s = replace_sep(m->otype, '_');
3362 args = get_arg_names_for_macro(m);
3364 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
3365 "\t{ if(%s_CLASS(parent_class)->%s) \\\n"
3366 "\t\t(* %s_CLASS(parent_class)->%s)(%s); }\n",
3367 args, s, m->id, s, m->id, args);
3369 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
3370 "\t((%s_CLASS(parent_class)->%s)? \\\n"
3371 "\t\t(* %s_CLASS(parent_class)->%s)(%s): \\\n"
3373 args, s, m->id, s, m->id, args);
3374 out_printf(out, "(");
3375 print_type(out, m->mtype, TRUE);
3376 out_printf(out, ")%s))\n",
3377 m->onerror?m->onerror:"0");
3381 print_method_body(m, TRUE, TRUE);
3382 /* the outfile line was added above */
3383 out_printf(out, "#undef PARENT_HANDLER\n");
3385 case CONSTRUCTOR_METHOD:
3386 case DISPOSE_METHOD:
3387 case FINALIZE_METHOD:
3389 out_addline_infile(out, m->line_no);
3390 print_method(out, "static ", "\n", "", " ", "", "\n",
3391 m, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE);
3392 print_method_body(m, TRUE, TRUE);
3393 /* the outfile line was added above */
3402 char *outfile, *outfileh, *outfileph;
3404 outfilebase = g_strconcat (fullfilebase, for_cpp ? ".cc" : ".c", NULL);
3405 outfile = g_strconcat(outfilebase, no_touch ? "#gob#" : "", NULL);
3407 outfilehbase = g_strconcat (fullfilebase, ".h", NULL);
3408 outfileh = g_strconcat(outfilehbase, no_touch_headers ? "#gob#" : "", NULL);
3410 if ((privates > 0 || protecteds > 0 ||
3411 private_header == PRIVATE_HEADER_ALWAYS) &&
3412 private_header != PRIVATE_HEADER_NEVER) {
3413 char sep[2] = {0,0};
3416 outfilephbase = g_strconcat (fullfilebase, sep, "private.h", NULL);
3417 outfileph = g_strconcat (outfilephbase, no_touch ? "#gob#" : "", NULL);
3419 outfilephbase = NULL;
3425 out = fopen (outfile, "w");
3427 error_printf (GOB_ERROR, 0,
3428 "Cannot open outfile: %s", outfile);
3430 outh = fopen (outfileh, "w");
3432 error_printf (GOB_ERROR, 0,
3433 "Cannot open outfile: %s", outfileh);
3435 if (outfileph != NULL) {
3436 outph = fopen (outfileph, "w");
3437 if (outph == NULL) {
3438 error_printf (GOB_ERROR, 0,
3439 "Cannot open outfile: %s",
3447 put_argument_nongnu_wrappers (Class *c)
3451 if (get_properties < 0 && set_properties < 0)
3454 for (li = c->nodes; li != NULL; li = li->next) {
3456 const char *name, *gtktype;
3462 if (n->type == ARGUMENT_NODE) {
3463 Argument *a = (Argument *)n;
3465 gtktype = a->gtktype;
3467 get = a->get != NULL;
3468 set = a->set != NULL;
3469 } else if (n->type == PROPERTY_NODE) {
3470 Property *p = (Property *)n;
3472 gtktype = p->gtktype;
3474 get = p->get != NULL;
3475 set = p->set != NULL;
3480 aname = g_strdup (name);
3484 cast = get_type (atype, TRUE);
3486 cast = g_strdup (get_cast (gtktype, TRUE));
3490 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3491 "\"%s\",(%s)(arg)\n",
3492 macrobase, aname, name, cast);
3494 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3495 "\"%s\",(%s*)(arg)\n",
3496 macrobase, aname, name, cast);
3499 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3501 macrobase, aname, name);
3503 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3505 macrobase, aname, name);
3513 put_argument_gnu_wrappers(Class *c)
3517 if(get_properties < 0 && set_properties < 0)
3520 for (li = c->nodes; li != NULL; li = li->next) {
3522 const char *name, *gtktype;
3528 if (n->type == ARGUMENT_NODE) {
3529 Argument *a = (Argument *)n;
3531 gtktype = a->gtktype;
3533 get = a->get != NULL;
3534 set = a->set != NULL;
3535 } else if (n->type == PROPERTY_NODE) {
3536 Property *p = (Property *)n;
3538 gtktype = p->gtktype;
3540 get = p->get != NULL;
3541 set = p->set != NULL;
3546 aname = g_strdup (name);
3550 cast = get_type (atype, TRUE);
3552 cast = g_strdup (get_cast (gtktype, TRUE));
3556 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3557 "\"%s\", __extension__ ({%sz = (arg); z;})\n",
3558 macrobase, aname, name, cast);
3560 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3561 "\"%s\", __extension__ ({%s*z = (arg); z;})\n",
3562 macrobase, aname, name, cast);
3565 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3567 macrobase, aname, name);
3569 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3571 macrobase, aname, name);
3579 print_ccode_block(CCode *cc)
3582 switch(cc->cctype) {
3584 /* HT code is printed exactly like normal header
3585 code but is printed before */
3588 out_printf(fp, "\n");
3591 /* AT code is printed exactly like normal 'all'
3592 code but is printed before */
3595 out_printf(outph, "\n");
3596 out_printf(outph, "%s\n", cc->cbuf);
3597 out_addline_infile(outph, cc->line_no);
3598 out_addline_outfile(outph);
3600 out_printf(outh, "\n");
3601 out_printf(outh, "%s\n", cc->cbuf);
3603 out_printf(fp, "\n");
3604 out_addline_infile(fp, cc->line_no);
3610 out_printf(fp, "\n");
3611 out_addline_infile(fp, cc->line_no);
3618 out_printf(fp, "\n");
3619 out_addline_infile(fp, cc->line_no);
3622 out_printf(fp, "%s\n", cc->cbuf);
3623 if(cc->cctype == C_CCODE ||
3624 cc->cctype == AD_CCODE ||
3625 cc->cctype == A_CCODE ||
3626 cc->cctype == AT_CCODE ||
3627 cc->cctype == PH_CCODE)
3628 out_addline_outfile(fp);
3632 print_class_block(Class *c)
3636 gboolean printed_private = FALSE;
3640 out_printf(outph ? outph : outh, "#include <gtk/gtk.h>\n");
3641 out_printf(outph ? outph : outh, "#include <glade/glade-xml.h>\n\n");
3645 out_printf(out, "/* utility types we may need */\n");
3646 if(special_array[SPECIAL_2POINTER])
3647 out_printf(out, "typedef struct { "
3648 "gpointer a; gpointer b; "
3649 "} ___twopointertype;\n");
3650 if(special_array[SPECIAL_3POINTER])
3651 out_printf(out, "typedef struct { "
3652 "gpointer a; gpointer b; "
3654 "} ___threepointertype;\n");
3655 if(special_array[SPECIAL_INT_POINTER])
3656 out_printf(out, "typedef struct { "
3657 "gint a; gpointer b; "
3658 "} ___intpointertype;\n");
3659 out_printf(out, "\n");
3662 out_printf(outh, "\n/*\n"
3663 " * Type checking and casting macros\n"
3665 out_printf(outh, "#define %s\t"
3666 "(%s_get_type())\n",
3667 macrotype, funcbase);
3668 out_printf(outh, "#define %s(obj)\t"
3669 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s)\n",
3670 macrobase, funcbase, typebase);
3671 out_printf(outh, "#define %s_CONST(obj)\t"
3672 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s const)\n",
3673 macrobase, funcbase, typebase);
3674 out_printf(outh, "#define %s_CLASS(klass)\t"
3675 "G_TYPE_CHECK_CLASS_CAST((klass), %s_get_type(), %sClass)\n",
3676 macrobase, funcbase, typebase);
3677 out_printf(outh, "#define %s(obj)\t"
3678 "G_TYPE_CHECK_INSTANCE_TYPE((obj), %s_get_type ())\n\n",
3681 "#define %s_GET_CLASS(obj)\t"
3682 "G_TYPE_INSTANCE_GET_CLASS((obj), %s_get_type(), %sClass)\n",
3683 macrobase, funcbase, typebase);
3685 if ( ! no_self_alias) {
3686 out_printf(out, "/* self casting macros */\n");
3687 out_printf(out, "#define SELF(x) %s(x)\n", macrobase);
3688 out_printf(out, "#define SELF_CONST(x) %s_CONST(x)\n", macrobase);
3689 out_printf(out, "#define IS_SELF(x) %s(x)\n", macrois);
3690 out_printf(out, "#define TYPE_SELF %s\n", macrotype);
3691 out_printf(out, "#define SELF_CLASS(x) %s_CLASS(x)\n\n",
3693 out_printf(out, "#define SELF_GET_CLASS(x) %s_GET_CLASS(x)\n\n",
3696 out_printf(out, "/* self typedefs */\n");
3697 out_printf(out, "typedef %s Self;\n", typebase);
3698 out_printf(out, "typedef %sClass SelfClass;\n\n", typebase);
3702 always_private_struct) {
3703 out_printf (outh, "\n/* Private structure type */\n");
3704 out_printf (outh, "typedef struct _%sPrivate %sPrivate;\n",
3705 typebase, typebase);
3707 out_printf (outh, "/* There are no privates, this "
3708 "structure is thus never defined */\n");
3711 out_printf (outh, "\n/*\n"
3712 " * Main object structure\n"
3714 s = replace_sep (c->otype, '_');
3716 out_printf (outh, "#ifndef __TYPEDEF_%s__\n"
3717 "#define __TYPEDEF_%s__\n", s, s);
3719 out_printf (outh, "typedef struct _%s %s;\n"
3720 "#endif\n", typebase, typebase);
3721 out_printf (outh, "struct _%s {\n\t%s __parent__;\n",
3722 typebase, ptypebase);
3723 for (li = c->nodes; li; li=li->next) {
3724 static gboolean printed_public = FALSE;
3726 Variable *v = (Variable *)n;
3727 if(n->type == VARIABLE_NODE &&
3728 v->scope == PUBLIC_SCOPE) {
3729 if( ! printed_public) {
3730 out_printf(outh, "\t/*< public >*/\n");
3731 printed_public = TRUE;
3733 put_variable((Variable *)n, outh);
3736 /* put protecteds always AFTER publics */
3737 for (li = c->nodes; li != NULL; li = li->next) {
3739 Variable *v = (Variable *)n;
3740 if (n->type == VARIABLE_NODE &&
3741 v->scope == PROTECTED_SCOPE) {
3742 if ( ! printed_private) {
3743 out_printf (outh, "\t/*< private >*/\n");
3744 printed_private = TRUE;
3746 put_variable ((Variable *)n, outh);
3750 always_private_struct) {
3751 if ( ! printed_private)
3752 out_printf (outh, "\t/*< private >*/\n");
3753 out_printf (outh, "\t%sPrivate *_priv;\n", typebase);
3755 out_printf (outh, "};\n");
3760 /* if we are to stick this into the private
3761 header, if not stick it directly into the
3768 out_printf (outfp, "struct _%sPrivate {\n",
3772 for(li=c->nodes; li; li=li->next) {
3774 Variable *v = (Variable *)n;
3775 if(n->type == VARIABLE_NODE &&
3776 v->scope == PRIVATE_SCOPE) {
3777 out_addline_infile(outfp, v->line_no);
3778 put_variable(v, outfp);
3781 out_addline_outfile(outfp);
3783 out_printf(outfp, "};\n");
3786 out_printf(outh, "\n/*\n"
3787 " * Class definition\n"
3789 out_printf(outh, "typedef struct _%sClass %sClass;\n",
3790 typebase, typebase);
3792 "struct _%sClass {\n\t%sClass __parent__;\n",
3793 typebase, ptypebase);
3794 for(li = c->nodes; li != NULL; li = li->next) {
3796 if(n->type == METHOD_NODE)
3797 put_vs_method((Method *)n);
3799 /* If BonoboX type class put down the epv */
3800 if (c->bonobo_object_class != NULL) {
3802 "\t/* Bonobo object epv */\n"
3803 "\tPOA_%s__epv _epv;\n",
3804 c->bonobo_object_class);
3806 /* put class scope variables */
3807 for (li = c->nodes; li != NULL; li = li->next) {
3809 Variable *v = (Variable *)n;
3810 if (n->type == VARIABLE_NODE &&
3811 v->scope == CLASS_SCOPE)
3812 put_variable ((Variable *)n, outh);
3814 out_printf (outh, "};\n\n");
3816 out_printf (out, "/* here are local prototypes */\n");
3817 if (set_properties > 0) {
3818 out_printf (out, "static void ___object_set_property "
3819 "(GObject *object, guint property_id, "
3820 "const GValue *value, GParamSpec *pspec);\n");
3822 if (get_properties > 0) {
3823 out_printf (out, "static void ___object_get_property "
3824 "(GObject *object, guint property_id, "
3825 "GValue *value, GParamSpec *pspec);\n");
3828 out_printf (outh, "\n/*\n"
3829 " * Public methods\n"
3832 if (!overrode_get_type) {
3834 * For ordinary "static" types it should be safe to mark the
3835 * get_type implementation as const, since the get_type
3836 * function return really is constant at the call boundary
3837 * (even though there is an initial setup on the first call).
3838 * But for dynamic types, since the registration is explicitly
3839 * separated, we need to settle for "pure" as the results of
3840 * get_type differ before and after type registration.
3842 out_printf(outh, "GType\t%s_get_type\t(void) %s;\n", funcbase,
3843 c->dynamic ? "G_GNUC_PURE" : "G_GNUC_CONST");
3847 out_printf(outh, "void\t%s_register_type\t(GTypeModule *);\n",
3851 for(li = c->nodes; li != NULL; li = li->next) {
3853 if(n->type == METHOD_NODE) {
3854 put_pub_method((Method *)n);
3855 put_prot_method((Method *)n);
3856 put_priv_method_prot((Method *)n);
3860 /* this idea is less and less apealing to me */
3862 out_printf (outh, "\n/*\n"
3863 " * Signal connection wrapper macros\n"
3866 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3867 put_signal_macros (c, TRUE);
3868 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3869 put_signal_macros (c, FALSE);
3870 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n");
3872 put_signal_macros (c, FALSE);
3873 out_printf(outh, "\n");
3876 out_printf (out, "\n/*\n"
3877 " * Signal connection wrapper macro shortcuts\n"
3879 put_local_signal_macros (c);
3880 out_printf(outh, "\n");
3883 /* argument wrapping macros */
3884 if(get_properties > 0 || set_properties > 0) {
3885 out_printf(outh, "\n/*\n"
3886 " * Argument wrapping macros\n"
3889 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3890 put_argument_gnu_wrappers(c);
3891 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3892 put_argument_nongnu_wrappers(c);
3893 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n");
3895 put_argument_nongnu_wrappers(c);
3900 for(li = c->nodes; li != NULL; li = li->next) {
3902 if(n->type == METHOD_NODE)
3903 add_signal_prots((Method *)n);
3909 if(any_method_to_alias(c)) {
3910 out_printf (out, "/* Short form macros */\n");
3911 make_method_aliases (c);
3914 add_interface_inits (c);
3916 if (!overrode_get_type) {
3917 if (c->bonobo_object_class != NULL)
3918 add_bonobo_object_get_type();
3919 else if (c->dynamic)
3920 add_dynamic_get_type();
3925 out_printf (out, "/* a macro for creating a new object of our type */\n");
3927 "#define GET_NEW ((%s *)g_object_new(%s_get_type(), NULL))\n\n",
3928 typebase, funcbase);
3930 out_printf (out, "/* a function for creating a new object of our type */\n");
3931 out_printf (out, "#include <stdarg.h>\n");
3933 "static %s * GET_NEW_VARG (const char *first, ...)%s;\n"
3934 "static %s *\nGET_NEW_VARG (const char *first, ...)\n"
3935 "{\n\t%s *ret;\n\tva_list ap;\n"
3936 "\tva_start (ap, first);\n"
3937 "\tret = (%s *)g_object_new_valist (%s_get_type (), "
3940 "\treturn ret;\n}\n\n",
3942 no_gnu ? "" : " G_GNUC_UNUSED",
3943 typebase, typebase, typebase, funcbase);
3947 out_printf (out, "/* a function to connect glade callback */\n");
3948 out_printf (out,"static void\n"
3949 "___glade_xml_connect_foreach(const gchar *handler_name,\n"
3950 "GObject *object,\n"
3951 "const gchar *signal_name,\n"
3952 "const gchar *signal_data,\n"
3953 "GObject *connect_object,\n"
3955 "gpointer user_data)\n"
3957 "\tstatic GModule * allsymbols = NULL;\n"
3959 "\tif (!allsymbols) allsymbols = g_module_open(NULL, 0);\n"
3960 "\tif (allsymbols) {\n"
3961 "\t\tgchar * func_name = g_strdup_printf(\"%s_%%s\", handler_name);\n"
3962 "\t\tGCallback func;\n"
3964 "\t\tif (!g_module_symbol(allsymbols, func_name, (gpointer)&func)){\n"
3965 "\t\t\tif (!g_module_symbol(allsymbols, handler_name, (gpointer)&func)) {\n"
3966 "\t\t\t\tg_warning(\"could not find signal handler '%%s'.\", func_name);\n"
3967 "\t\t\t\tg_free(func_name);\n"
3972 "\t\t\tg_signal_connect_data(object, signal_name, func, user_data, NULL, G_CONNECT_AFTER | G_CONNECT_SWAPPED);\n"
3974 "\t\t\tg_signal_connect_data(object, signal_name, func, user_data, NULL, G_CONNECT_SWAPPED);\n"
3975 "\t\tg_free(func_name);\n"
3982 for (li = nodes; li != NULL; li = li->next) {
3983 Node *node = li->data;
3984 if (node->type == CCODE_NODE) {
3985 CCode *cc = (CCode *)node;
3986 if (cc->cctype == AD_CCODE)
3987 print_ccode_block (cc);
3991 if (need_constructor)
3992 add_constructor (c);
4002 if(set_properties > 0) {
4003 add_getset_arg(c, TRUE);
4006 if(get_properties > 0) {
4007 add_getset_arg(c, FALSE);
4010 for(li = c->nodes; li != NULL; li = li->next) {
4012 if(n->type == METHOD_NODE)
4013 put_method((Method *)n);
4016 add_bad_hack_to_avoid_unused_warnings(c);
4020 print_useful_macros(void)
4022 int major = 0, minor = 0, pl = 0;
4025 sscanf (VERSION, "%d.%d.%d", &major, &minor, &pl);
4026 out_printf (out, "#define GOB_VERSION_MAJOR %d\n", major);
4027 out_printf (out, "#define GOB_VERSION_MINOR %d\n", minor);
4028 out_printf (out, "#define GOB_VERSION_PATCHLEVEL %d\n\n", pl);
4030 /* Useful priv macro thingie */
4031 /* FIXME: this should be done the same way that priv is, as a var,
4033 out_printf (out, "#define selfp (self->_priv)\n\n");
4037 print_more_useful_macros (void)
4040 out_printf (out, "#define ___GOB_LIKELY(expr) (expr)\n");
4041 out_printf (out, "#define ___GOB_UNLIKELY(expr) (expr)\n");
4043 out_printf (out, "#ifdef G_LIKELY\n");
4044 out_printf (out, "#define ___GOB_LIKELY(expr) G_LIKELY(expr)\n");
4045 out_printf (out, "#define ___GOB_UNLIKELY(expr) G_UNLIKELY(expr)\n");
4046 out_printf (out, "#else /* ! G_LIKELY */\n");
4047 out_printf (out, "#define ___GOB_LIKELY(expr) (expr)\n");
4048 out_printf (out, "#define ___GOB_UNLIKELY(expr) (expr)\n");
4049 out_printf (out, "#endif /* G_LIKELY */\n");
4054 print_file_comments(void)
4056 out_printf(outh, "/* Generated by GOB (v%s)"
4057 " (do not edit directly) */\n\n", VERSION);
4059 out_printf(outph, "/* Generated by GOB (v%s)"
4060 " (do not edit directly) */\n\n", VERSION);
4061 out_printf(out, "/* Generated by GOB (v%s)"
4062 " (do not edit directly) */\n\n", VERSION);
4064 out_printf(out, "/* End world hunger, donate to the World Food Programme, http://www.wfp.org */\n\n");
4068 print_includes(void)
4070 gboolean found_header;
4073 /* We may need string.h for memset */
4074 if ( ! g_list_find_custom(include_files, "string.h", (GCompareFunc)strcmp)) {
4075 out_printf(out, "#include <string.h> /* memset() */\n\n");
4078 p = g_strconcat(filebase, ".h", NULL);
4079 found_header = TRUE;
4080 if( ! g_list_find_custom(include_files, p, (GCompareFunc)strcmp)) {
4081 out_printf(out, "#include \"%s.h\"\n\n", filebase);
4082 found_header = FALSE;
4086 /* if we are creating a private header see if it was included */
4088 char sep[2] = {0,0};
4091 p = g_strconcat(filebase, sep, "private.h", NULL);
4092 if( ! g_list_find_custom(include_files, p,
4093 (GCompareFunc)strcmp)) {
4094 out_printf(out, "#include \"%s%sprivate.h\"\n\n",
4098 error_printf(GOB_WARN, 0,
4099 "Implicit private header include "
4101 "\tsource file, while public "
4102 "header is at a custom location, "
4104 "\texplicitly include "
4105 "the private header below the "
4113 print_header_prefixes(void)
4117 p = replace_sep(((Class *)class)->otype, '_');
4119 out_printf(outh, "#ifndef __%s_H__\n#define __%s_H__\n\n", p, p);
4121 out_printf(outph, "#ifndef __%s_PRIVATE_H__\n"
4122 "#define __%s_PRIVATE_H__\n\n"
4123 "#include \"%s.h\"\n\n", p, p, filebase);
4126 if( ! no_extern_c) {
4127 out_printf(outh, "#ifdef __cplusplus\n"
4129 "#endif /* __cplusplus */\n\n");
4131 out_printf(outph, "#ifdef __cplusplus\n"
4133 "#endif /* __cplusplus */\n\n");
4138 print_header_postfixes(void)
4141 out_printf(outh, "\n#ifdef __cplusplus\n"
4143 "#endif /* __cplusplus */\n");
4144 out_printf(outh, "\n#endif\n");
4147 out_printf(outph, "\n#ifdef __cplusplus\n"
4149 "#endif /* __cplusplus */\n");
4150 out_printf(outph, "\n#endif\n");
4159 /* print the AT_CCODE and CT_CCODE blocks */
4160 for(li = nodes; li != NULL; li = li->next) {
4161 Node *node = li->data;
4162 if(node->type == CCODE_NODE) {
4163 CCode *cc = (CCode *)node;
4164 if (cc->cctype == AT_CCODE ||
4165 cc->cctype == CT_CCODE)
4166 print_ccode_block((CCode *)node);
4172 print_header_top(void)
4176 /* mandatory includes */
4177 out_printf (outh, "#include <glib.h>\n");
4178 out_printf (outh, "#include <glib-object.h>\n");
4180 /* print the HT_CCODE blocks */
4181 for (li = nodes; li != NULL; li = li->next) {
4182 Node *node = li->data;
4183 if (node->type == CCODE_NODE) {
4184 CCode *cc = (CCode *)node;
4185 if (cc->cctype == HT_CCODE)
4186 print_ccode_block ((CCode *)node);
4192 print_enum (EnumDef *enode)
4199 funcprefix = replace_sep (enode->etype, '_');
4200 gob_strdown (funcprefix);
4201 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
4203 type = remove_sep (enode->etype);
4205 out_printf (outh, "\ntypedef enum {\n");
4207 for (li = enode->values; li != NULL; li = li->next) {
4208 EnumValue *value = li->data;
4210 char *sname = gob_strdown (g_strdup (value->name));
4212 while ((p = strchr (sname, '_')) != NULL)
4215 out_printf (outh, "\t%s_%s", enode->prefix, value->name);
4216 if (value->value != NULL)
4217 out_printf (outh, " = %s", value->value);
4218 if (li->next != NULL)
4219 out_printf (outh, ",\n");
4221 out_printf (outh, "\n");
4223 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
4224 enode->prefix, value->name,
4225 enode->prefix, value->name,
4231 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
4233 out_printf (outh, "} %s;\n", type);
4235 str = make_pre_macro (enode->etype, "TYPE");
4236 out_printf (outh, "#define %s ", str);
4239 out_printf (outh, "%s_get_type()\n", funcprefix);
4240 out_printf (outh, "GType %s_get_type (void) G_GNUC_CONST;\n\n", funcprefix);
4243 "GType\n%s_get_type (void)\n"
4245 "\tstatic GType type = 0;\n"
4246 "\tif ___GOB_UNLIKELY(type == 0)\n"
4247 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
4250 funcprefix, type, funcprefix);
4252 g_free (funcprefix);
4257 print_flags (Flags *fnode)
4265 funcprefix = replace_sep (fnode->ftype, '_');
4266 gob_strdown (funcprefix);
4267 out_printf (out, "static const GFlagsValue _%s_values[] = {\n",
4269 type = remove_sep (fnode->ftype);
4271 out_printf (outh, "\ntypedef enum {\n");
4273 for (i = 0, li = fnode->values; li != NULL; i++, li = li->next) {
4274 const char *name = li->data;
4276 char *sname = gob_strdown (g_strdup (name));
4278 while ((p = strchr (sname, '_')) != NULL)
4281 out_printf (outh, "\t%s_%s = 1<<%d",
4282 fnode->prefix, name, i);
4283 if (li->next != NULL)
4284 out_printf (outh, ",\n");
4286 out_printf (outh, "\n");
4288 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
4289 fnode->prefix, name,
4290 fnode->prefix, name,
4296 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
4298 out_printf (outh, "} %s;\n", type);
4300 str = make_pre_macro (fnode->ftype, "TYPE");
4301 out_printf (outh, "#define %s ", str);
4304 out_printf (outh, "%s_get_type()\n", funcprefix);
4305 out_printf (outh, "GType %s_get_type (void) G_GNUC_CONST;\n\n", funcprefix);
4308 "GType\n%s_get_type (void)\n"
4310 "\tstatic GType type = 0;\n"
4311 "\tif ___GOB_UNLIKELY(type == 0)\n"
4312 "\t\ttype = g_flags_register_static (\"%s\", _%s_values);\n"
4315 funcprefix, type, funcprefix);
4317 g_free (funcprefix);
4322 print_error (Error *enode)
4329 funcprefix = replace_sep (enode->etype, '_');
4330 gob_strdown (funcprefix);
4331 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
4333 type = remove_sep (enode->etype);
4335 out_printf (outh, "\ntypedef enum {\n");
4337 for (li = enode->values; li != NULL; li = li->next) {
4338 const char *name = li->data;
4340 char *sname = gob_strdown (g_strdup (name));
4342 while ((p = strchr (sname, '_')) != NULL)
4345 out_printf (outh, "\t%s_%s", enode->prefix, name);
4346 if (li->next != NULL)
4347 out_printf (outh, ",\n");
4349 out_printf (outh, "\n");
4351 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
4352 enode->prefix, name,
4353 enode->prefix, name,
4359 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
4361 out_printf (outh, "} %s;\n", type);
4363 str = make_pre_macro (enode->etype, "TYPE");
4364 out_printf (outh, "#define %s ", str);
4367 out_printf (outh, "%s_get_type ()\n", funcprefix);
4368 out_printf (outh, "GType %s_get_type (void) G_GNUC_CONST;\n\n", funcprefix);
4371 "GType\n%s_get_type (void)\n"
4373 "\tstatic GType type = 0;\n"
4374 "\tif ___GOB_UNLIKELY(type == 0)\n"
4375 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
4378 funcprefix, type, funcprefix);
4380 out_printf (outh, "#define %s %s_quark ()\n", enode->prefix, funcprefix);
4381 out_printf (outh, "GQuark %s_quark (void);\n\n", funcprefix);
4383 str = replace_sep (enode->etype, '-');
4387 "GQuark\n%s_quark (void)\n"
4389 "\tstatic GQuark q = 0;\n"
4391 "\t\tq = g_quark_from_static_string (\"%s\");\n"
4398 g_free (funcprefix);
4403 generate_outfiles(void)
4407 print_file_comments();
4413 print_header_prefixes();
4415 print_useful_macros();
4419 print_more_useful_macros ();
4421 for (li = nodes; li != NULL; li = li->next) {
4422 Node *node = li->data;
4423 if (node->type == CCODE_NODE) {
4424 CCode *cc = (CCode *)node;
4425 if (cc->cctype != HT_CCODE &&
4426 cc->cctype != AT_CCODE &&
4427 cc->cctype != AD_CCODE)
4428 print_ccode_block ((CCode *)node);
4429 } else if (node->type == CLASS_NODE) {
4430 print_class_block ((Class *)node);
4431 } else if (node->type == ENUMDEF_NODE) {
4432 print_enum ((EnumDef *)node);
4433 } else if (node->type == FLAGS_NODE) {
4434 print_flags ((Flags *)node);
4435 } else if (node->type == ERROR_NODE) {
4436 print_error ((Error *)node);
4438 g_assert_not_reached();
4442 print_header_postfixes();
4448 fprintf(stderr, "Gob version %s\n\n", VERSION);
4449 fprintf(stderr, "gob [options] file.gob\n\n");
4450 fprintf(stderr, "Options:\n"
4451 "\t--help,-h,-? Display this help\n"
4452 "\t--version Display version\n"
4453 "\t--exit-on-warn,-w Exit with an error on warnings\n"
4454 "\t--no-exit-on-warn Don't exit on warnings [default]\n"
4455 "\t--for-cpp Create C++ files\n"
4456 "\t--no-extern-c Never print extern \"C\" into the "
4458 "\t--no-gnu Never use GNU extentions\n"
4459 "\t--no-touch Don't touch output files unless they "
4461 "\t changed (implies --no-touch-headers)\n"
4462 "\t--no-touch-headers Don't touch headers unless they "
4464 "\t--always-private-header Always create a private header "
4466 "\t even if it would be empty\n"
4467 "\t--ondemand-private-header Create private header only when "
4470 "\t--no-private-header Don't create a private header, "
4472 "\t structure and protected "
4473 "prototypes inside c file\n"
4474 "\t--always-private-struct Always create a private pointer "
4476 "\t the object structure\n"
4477 "\t--m4 Preprocess source with m4. "
4478 "Following args will\n"
4479 "\t be passed to m4\n"
4480 "\t--m4-dir Print directory that will be "
4483 "\t--no-write,-n Don't write output files, just "
4485 "\t--no-lines Don't print '#line' to output\n"
4486 "\t--no-self-alias Don't create self type and macro "
4488 "\t--no-kill-underscores Ignored for compatibility\n"
4489 "\t-o,--output-dir The directory where output "
4490 "should be placed\n"
4491 "\t--file-sep[=c] replace default \'-\' file "
4492 "name separator\n\n"
4493 "\t--gtk3 Use gtk+3\n"
4495 fprintf(stderr, "End world hunger, donate to the World Food Programme, http://www.wfp.org\n");
4499 parse_options(int argc, char *argv[])
4502 int got_file = FALSE;
4503 int no_opts = FALSE;
4504 int m4_opts = FALSE; /* if we are just passing on args to m4 */
4508 for(i = 1 ; i < argc; i++) {
4510 char *new_commandline;
4511 g_assert(m4_commandline!=NULL);
4513 /* check whether this one looks like the filename */
4514 if((!strcmp(argv[i],"-") || argv[i][0] != '-')
4516 const gchar *m4_flags=use_m4_clean?"":M4_FLAGS;
4520 /* insert flags before the filename */
4521 new_commandline=g_strconcat(m4_commandline,
4529 /* just an ordinary option */
4531 new_commandline=g_strconcat(m4_commandline,
4536 /* free old commandline */
4537 g_free(m4_commandline);
4538 m4_commandline=new_commandline;
4540 } else if(no_opts ||
4541 argv[i][0] != '-') {
4544 fprintf(stderr, "Specify only one file!\n");
4550 } else if(strcmp(argv[i], "--help")==0) {
4553 } else if(strcmp(argv[i], "--version")==0) {
4554 fprintf(stderr, "Gob version %s\n", VERSION);
4556 } else if(strcmp(argv[i], "--exit-on-warn")==0) {
4557 exit_on_warn = TRUE;
4558 } else if(strcmp(argv[i], "--no-exit-on-warn")==0) {
4559 exit_on_warn = FALSE;
4560 } else if(strcmp(argv[i], "--for-cpp")==0) {
4562 } else if(strcmp(argv[i], "--no-touch")==0) {
4564 no_touch_headers = TRUE;
4565 } else if(strcmp(argv[i], "--no-touch-headers")==0) {
4566 no_touch_headers = TRUE;
4567 } else if(strcmp(argv[i], "--ondemand-private-header")==0) {
4568 private_header = PRIVATE_HEADER_ONDEMAND;
4569 } else if(strcmp(argv[i], "--always-private-header")==0) {
4570 private_header = PRIVATE_HEADER_ALWAYS;
4571 } else if(strcmp(argv[i], "--no-private-header")==0) {
4572 private_header = PRIVATE_HEADER_NEVER;
4573 } else if(strcmp(argv[i], "--no-gnu")==0) {
4575 } else if(strcmp(argv[i], "--no-extern-c")==0) {
4577 } else if(strcmp(argv[i], "--no-write")==0) {
4579 } else if(strcmp(argv[i], "--no-lines")==0) {
4581 } else if(strcmp(argv[i], "--no-self-alias")==0) {
4582 no_self_alias = TRUE;
4583 } else if(strcmp(argv[i], "--no-kill-underscores")==0) {
4585 } else if(strcmp(argv[i], "--always-private-struct")==0) {
4586 always_private_struct = TRUE;
4587 } else if(strcmp(argv[i], "--m4-dir")==0) {
4588 printf("%s\n",M4_INCLUDE_DIR);
4590 } else if(strcmp(argv[i], "--m4")==0) {
4594 m4_commandline=g_strdup(M4_COMMANDLINE);
4595 } else if(strcmp(argv[i], "--m4-clean")==0) {
4599 m4_commandline=g_strdup(M4_COMMANDLINE);
4600 } else if (strcmp (argv[i], "-o") == 0 ||
4601 strcmp (argv[i], "--output-dir") == 0) {
4603 output_dir = g_strdup (argv[i+1]);
4608 } else if (strncmp (argv[i], "-o=", strlen ("-o=")) == 0 ||
4611 strlen ("--output-dir=")) == 0) {
4612 char *p = strchr (argv[i], '=');
4613 g_assert (p != NULL);
4614 output_dir = g_strdup (p+1);
4615 } else if (strncmp (argv[i], "--file-sep=",
4616 strlen ("--file-sep=")) == 0) {
4617 char *p = strchr (argv[i], '=');
4618 g_assert (p != NULL);
4620 } else if (strncmp (argv[i], "--file-sep",
4621 strlen ("--file-sep")) == 0) {
4623 file_sep = (argv[i+1])[0];
4628 } else if(strcmp(argv[i], "--gtk3")==0) {
4630 } else if(strcmp(argv[i], "--")==0) {
4631 /*further arguments are files*/
4633 } else if(strncmp(argv[i], "--", 2)==0) {
4634 /*unknown long option*/
4635 fprintf(stderr, "Unknown option '%s'!\n", argv[i]);
4639 /*by now we know we have a string starting with
4640 - which is a short option string*/
4642 for(p = argv[i] + 1; *p; p++) {
4656 "Unknown option '%c'!\n", *p);
4665 /* if we are using m4, and got no filename, append m4 flags now */
4666 if(!got_file && use_m4 && !use_m4_clean) {
4667 char *new_commandline;
4668 new_commandline=g_strconcat(m4_commandline,
4672 g_free(m4_commandline);
4673 m4_commandline=new_commandline;
4679 compare_and_move (const char *old_filename)
4681 char *new_filename = g_strconcat (old_filename, "#gob#", NULL);
4683 gboolean equal = FALSE;
4685 old_f = fopen (old_filename, "r");
4688 gboolean error = FALSE;
4690 new_f = fopen (new_filename, "r");
4699 new_n = fread (new_buf, 1, sizeof (new_buf), new_f);
4700 if (ferror (new_f)) {
4702 error_printf (GOB_ERROR, 0,
4703 "Can't read %s: %s",
4705 g_strerror (errno));
4709 old_n = fread (old_buf, 1, sizeof (old_buf), old_f);
4711 || feof (new_f) != feof (old_f)
4713 || memcmp (new_buf, old_buf, new_n) != 0)
4722 error_printf (GOB_ERROR, 0, "Can't open %s: %s",
4723 new_filename, g_strerror (errno));
4731 if (! equal && unlink (old_filename) != 0) {
4732 error_printf (GOB_ERROR, 0, "Can't remove %s: %s",
4733 old_filename, g_strerror (errno));
4739 if (unlink (new_filename) != 0)
4740 error_printf (GOB_ERROR, 0, "Can't remove %s: %s",
4741 new_filename, g_strerror (errno));
4743 if (rename (new_filename, old_filename) != 0)
4744 error_printf (GOB_ERROR, 0, "Can't rename %s to %s: %s",
4745 new_filename, old_filename,
4746 g_strerror (errno));
4750 g_free (new_filename);
4754 main(int argc, char *argv[])
4756 parse_options(argc, argv);
4759 yyin = popen(m4_commandline, "r");
4761 fprintf(stderr, "Error: can't open pipe from '%s'\n",
4765 } else if(filename) {
4766 yyin = fopen(filename, "r");
4768 fprintf(stderr, "Error: can't open file '%s'\n",
4777 /* This is where parsing is done */
4780 error_print (GOB_ERROR, 0, "Parsing errors, quitting");
4782 /* close input file */
4783 if(use_m4) pclose(yyin);
4788 error_print (GOB_ERROR, 0, "no class defined");
4791 exit_on_error = FALSE;
4793 signals = count_signals ((Class *)class);
4794 set_properties = count_set_properties ((Class *)class) +
4795 count_set_arguments ((Class *)class);
4796 get_properties = count_get_properties ((Class *)class) +
4797 count_get_arguments ((Class *)class);
4798 overrides = count_overrides ((Class *)class);
4799 privates = count_privates ((Class *)class);
4800 protecteds = count_protecteds ((Class *)class);
4801 unreftors = count_unreftors ((Class *)class);
4802 destructors = count_destructors ((Class *)class);
4803 initializers = count_initializers ((Class *)class);
4804 glade_widgets = count_glade_widgets ((Class *)class);
4805 overrode_get_type = find_get_type ((Class *)class);
4808 make_inits ((Class *)class);
4810 find_constructor ((Class *)class);
4811 if (user_constructor != NULL)
4812 need_constructor = TRUE;
4814 find_dispose ((Class *)class);
4815 if (unreftors > 0 ||
4816 dispose_handler != NULL ||
4817 user_dispose_method != NULL)
4818 need_dispose = TRUE;
4820 find_finalize ((Class *)class);
4821 if (destructors > 0 ||
4823 user_finalize_method != NULL) {
4824 need_finalize = TRUE;
4827 check_bad_symbols ((Class *)class);
4828 check_duplicate_symbols ((Class *)class);
4829 check_duplicate_overrides ((Class *)class);
4830 check_duplicate_signals_args ((Class *)class);
4831 check_public_new ((Class *)class);
4832 check_vararg ((Class *)class);
4833 check_firstarg ((Class *)class);
4834 check_nonvoidempty ((Class *)class);
4835 check_signal_args ((Class *)class);
4836 check_property_types ((Class *)class);
4837 check_argument_types ((Class *)class);
4838 check_func_arg_checks ((Class *)class);
4839 check_func_attrs ((Class *)class);
4840 check_for_class_destructors ((Class *)class);
4842 exit_on_error = TRUE;
4847 any_special = setup_special_array ((Class *)class, special_array);
4851 generate_outfiles ();
4862 compare_and_move (outfilebase);
4864 compare_and_move (outfilephbase);
4866 if (no_touch_headers)
4867 compare_and_move (outfilehbase);