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");
961 out_printf(out, "\n");
963 out_printf(out, "enum {\n");
964 for(li=c->nodes;li;li=g_list_next(li)) {
966 if(n->type == METHOD_NODE) {
967 Method *m = (Method *)n;
968 if(m->method == SIGNAL_LAST_METHOD ||
969 m->method == SIGNAL_FIRST_METHOD) {
970 char *s = g_strdup(m->id);
972 out_printf(out, "\t%s_SIGNAL,\n", s);
977 out_printf(out, "\tLAST_SIGNAL\n};\n\n");
979 if (set_properties > 0 ||
980 get_properties > 0) {
981 out_printf(out, "enum {\n\tPROP_0");
982 for(li=c->nodes;li;li=g_list_next(li)) {
984 if (n->type == PROPERTY_NODE) {
985 Property *p = (Property *)n;
986 char *s = g_strdup (p->name);
988 out_printf (out, ",\n\tPROP_%s", s);
990 } else if (n->type == ARGUMENT_NODE) {
991 Argument *a = (Argument *)n;
992 char *s = g_strdup(a->name);
994 out_printf(out, ",\n\tPROP_%s", s);
998 out_printf(out, "\n};\n\n");
1003 "static guint object_signals[LAST_SIGNAL] = {0};\n\n");
1005 out_printf(out, "/* pointer to the class of our parent */\n");
1006 out_printf(out, "static %sClass *parent_class = NULL;\n\n", ptypebase);
1010 add_interface_methods (Class *c, const char *interface)
1013 gboolean added_line = FALSE;
1015 for (li = c->nodes; li != NULL; li = li->next) {
1017 Method *m = (Method *)n;
1018 if (n->type != METHOD_NODE ||
1019 m->method == OVERRIDE_METHOD ||
1020 m->interface == NULL ||
1021 strcmp (m->interface, interface) != 0)
1024 if (m->line_no > 0) {
1025 out_addline_infile (out, m->line_no);
1027 } else if (m->line_no == 0 &&
1029 out_addline_outfile (out);
1032 out_printf (out, "\tiface->%s = self_%s;\n",
1036 out_addline_outfile (out);
1040 add_interface_inits (Class *c)
1044 if (c->interfaces == NULL)
1047 out_printf(out, "\n");
1049 for (li = c->interfaces; li != NULL; li = li->next) {
1050 const char *interface = li->data;
1052 char *name = replace_sep (interface, '_');
1053 char *type = remove_sep (interface);
1057 /* EEEK! evil, we should have some sort of option
1058 * to force this for arbitrary interfaces, since
1059 * some are Class and some are Iface. Glib is shite
1060 * in consistency. */
1062 if (strcmp (type, "GtkEditable") == 0 ||
1063 strcmp (type, "GTypePlugin") == 0)
1066 // We'll assume Iface is the standard ending
1071 /*GTK3 doesn't need Iface end*/
1075 out_printf (out, "\nstatic void\n"
1076 "___%s_init (%s%s *iface)\n"
1080 add_interface_methods (c, interface);
1082 out_printf (out, "}\n\n");
1090 add_interface_infos (void)
1093 for (li = ((Class *)class)->interfaces;
1096 char *name = replace_sep (li->data, '_');
1098 "\t\tstatic const GInterfaceInfo %s_info = {\n"
1099 "\t\t\t(GInterfaceInitFunc) ___%s_init,\n"
1109 add_interfaces (void)
1112 for (li = ((Class *)class)->interfaces;
1115 char *name = replace_sep (li->data, '_');
1116 char *type = make_pre_macro (li->data, "TYPE");
1119 "\t\tg_type_add_interface_static (type,\n"
1121 "\t\t\t&%s_info);\n",
1131 add_dynamic_interfaces(void)
1133 GList *li = ((Class *)class)->interfaces;
1137 * Hack to work around bug in g_type_module_add_interface,
1138 * which will fail to add an interface to types that derive
1139 * from something that also implements the same interface.
1141 * The actual GType system does not have any such problem,
1142 * and the GTypeModule implementation details relied upon
1143 * here have not changed once since the feature was first
1144 * implemented almost 20 years ago.
1146 out_printf(out, "\t\tstruct _ModuleInterfaceInfo {\n"
1147 "\t\t\tgboolean loaded;\n"
1148 "\t\t\tGType instance_type;\n"
1149 "\t\t\tGType interface_type;\n"
1150 "\t\t\tGInterfaceInfo info;\n"
1151 "\t\t} *modinfo;\n");
1154 for (; li; li = li->next) {
1155 char *name = replace_sep(li->data, '_');
1156 char *type = make_pre_macro(li->data, "TYPE");
1158 out_printf(out, "\n"
1159 "\t\tmodinfo = g_malloc(sizeof *modinfo);\n"
1160 "\t\tmodinfo->loaded = TRUE;\n"
1161 "\t\tmodinfo->instance_type = %s_type_id;\n"
1162 "\t\tmodinfo->interface_type = %s;\n"
1163 "\t\tmodinfo->info = %s_info;\n"
1164 "\t\tg_type_add_interface_dynamic\n"
1165 "\t\t\t( modinfo->instance_type\n"
1166 "\t\t\t, modinfo->interface_type\n"
1167 "\t\t\t, G_TYPE_PLUGIN(type_module)\n"
1169 "\t\ttype_module->interface_infos = g_slist_prepend\n"
1170 "\t\t\t( type_module->interface_infos\n"
1172 "\t\t\t);\n", funcbase, type, name);
1182 /*char *chunk_size = ((Class*)class)->chunk_size;*/
1186 "%s_get_type (void)\n"
1188 "\tstatic GType type = 0;\n\n"
1189 "\tif ___GOB_UNLIKELY(type == 0) {\n"
1190 "\t\tstatic const GTypeInfo info = {\n"
1191 "\t\t\tsizeof (%sClass),\n"
1192 "\t\t\t(GBaseInitFunc) NULL,\n"
1193 "\t\t\t(GBaseFinalizeFunc) NULL,\n"
1194 "\t\t\t(GClassInitFunc) %s_class_init,\n"
1195 "\t\t\t(GClassFinalizeFunc) NULL,\n"
1196 "\t\t\tNULL /* class_data */,\n"
1197 "\t\t\tsizeof (%s),\n"
1198 "\t\t\t%d /* n_preallocs */,\n"
1199 "\t\t\t(GInstanceInitFunc) %s_init,\n"
1202 funcbase, typebase, funcbase, typebase, prealloc, funcbase);
1204 add_interface_infos ();
1207 "\t\ttype = g_type_register_static (%s, \"%s\", &info, (GTypeFlags)%s);\n",
1208 pmacrotype, typebase, ((Class *)class)->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0");
1216 "\t\tgtk_type_set_chunk_alloc(type, %s);\n"
1218 chunk_size, chunk_size);
1228 add_dynamic_get_type (void)
1231 "static GType %s_type_id;\n\n"
1233 "%s_get_type (void)\n"
1235 "\treturn %s_type_id;\n"
1237 funcbase, funcbase, funcbase);
1241 "%s_register_type (GTypeModule *type_module)\n"
1243 "\tstatic const GTypeInfo info = {\n"
1244 "\t\tsizeof (%sClass),\n"
1245 "\t\t(GBaseInitFunc) NULL,\n"
1246 "\t\t(GBaseFinalizeFunc) NULL,\n"
1247 "\t\t(GClassInitFunc) %s_class_init,\n"
1248 "\t\t(GClassFinalizeFunc) NULL,\n"
1249 "\t\tNULL /* class_data */,\n"
1250 "\t\tsizeof (%s),\n"
1251 "\t\t%d /* n_preallocs */,\n"
1252 "\t\t(GInstanceInitFunc) %s_init,\n"
1255 funcbase, typebase, funcbase, typebase, prealloc, funcbase);
1257 add_interface_infos();
1260 "\t%s_type_id = g_type_module_register_type(\n"
1261 "\t\ttype_module,\n"
1265 "\t\t(GTypeFlags)%s\n"
1268 funcbase, pmacrotype, typebase,
1269 ((Class *)class)->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0");
1271 add_dynamic_interfaces();
1279 add_bonobo_object_get_type (void)
1281 /* char *chunk_size = ((Class*)class)->chunk_size; */
1282 /* _vicious_ spanks seth with a rusty nail
1284 "\n#warning \"Bonobo isn't fully ported to glib 2.0 and "
1285 "gob2 doesn't officially support it yet. It'd be safer "
1286 "and a lot more fun to blow goats.\"\n");
1291 "%s_get_type (void)\n" /* 1 */
1293 "\tstatic GType type = 0;\n\n"
1294 "\tif ___GOB_UNLIKELY(type == 0) {\n"
1295 "\t\tstatic const GTypeInfo info = {\n"
1296 "\t\t\tsizeof (%sClass),\n" /* 2 */
1297 "\t\t\t(GBaseInitFunc) NULL,\n"
1298 "\t\t\t(GBaseFinalizeFunc) NULL,\n"
1299 "\t\t\t(GClassInitFunc) %s_class_init,\n" /* 3 */
1300 "\t\t\tNULL, /* class_finalize */\n"
1301 "\t\t\tNULL, /* class_data */\n"
1302 "\t\t\tsizeof (%s),\n" /* 4 */
1303 "\t\t\t0, /* n_preallocs */\n"
1304 "\t\t\t(GInstanceInitFunc) %s_init,\n" /* 5 */
1313 add_interface_infos ();
1316 "\t\ttype = bonobo_type_unique (\n"
1317 "\t\t\tBONOBO_OBJECT_TYPE,\n"
1318 "\t\t\tPOA_%s__init, NULL,\n" /* 1 */
1319 "\t\t\tG_STRUCT_OFFSET (%sClass, _epv),\n" /* 2 */
1320 "\t\t\t&info, \"%s\");\n", /* 3 */
1321 ((Class*)class)->bonobo_object_class /* 1 */,
1330 "\t\tgtk_type_set_chunk_alloc(type, %s);\n"
1332 chunk_size, chunk_size);
1341 add_overrides(Class *c, const char *oname,
1342 gboolean did_base_obj)
1348 done = g_hash_table_new (g_str_hash, g_str_equal);
1350 s = g_strdup ("GObject");
1351 g_hash_table_insert (done, s, s);
1353 for (li = c->nodes; li != NULL; li = li->next) {
1356 Method *m = (Method *)n;
1357 if(n->type != METHOD_NODE ||
1358 m->method != OVERRIDE_METHOD)
1361 s = remove_sep(m->otype);
1363 if(g_hash_table_lookup(done, s)) {
1367 g_hash_table_insert(done, s, s);
1369 f = replace_sep(m->otype, '_');
1372 out_printf(out, "\t%sClass *%s_class = (%sClass *)%s;\n",
1377 g_hash_table_foreach (done, (GHFunc)g_free, NULL);
1378 g_hash_table_destroy (done);
1382 make_run_signal_flags(Method *m, gboolean last)
1397 gs = g_string_new(NULL);
1400 g_string_assign(gs, "G_SIGNAL_RUN_LAST");
1402 g_string_assign(gs, "G_SIGNAL_RUN_FIRST");
1404 if(m->scope == PUBLIC_SCOPE)
1405 g_string_append(gs, " | G_SIGNAL_ACTION");
1407 for(li = m->flags; li; li = li->next) {
1408 char *flag = li->data;
1410 for(i=0;flags[i];i++) {
1411 if(strcmp(flags[i], flag)==0)
1414 /* if we haven't found it in our list */
1416 error_printf(GOB_WARN, m->line_no,
1417 "Unknown flag '%s' used, "
1418 "perhaps it was misspelled",
1421 g_string_sprintfa(gs, " | G_SIGNAL_%s", flag);
1425 char *ret = gs->str;
1426 g_string_free(gs, FALSE);
1433 add_signals(Class *c)
1437 out_printf(out, "\n");
1438 for(li=c->nodes;li;li=g_list_next(li)) {
1440 char *mar, *sig, *flags;
1441 gboolean is_none, last = FALSE;
1442 Method *m = (Method *)n;
1444 if(n->type != METHOD_NODE ||
1445 (m->method != SIGNAL_FIRST_METHOD &&
1446 m->method != SIGNAL_LAST_METHOD))
1449 if(m->method == SIGNAL_FIRST_METHOD)
1454 if(g_hash_table_lookup(marsh, m))
1455 mar = g_strconcat("___marshal_",
1456 (char *)g_hash_table_lookup(marsh, m),
1459 mar = g_strdup("g_cclosure_marshal_VOID__VOID");
1461 is_none = (strcmp(m->gtktypes->next->data, "NONE")==0);
1463 sig = g_strdup (m->id);
1465 flags = make_run_signal_flags (m, last);
1466 out_printf (out, "\tobject_signals[%s_SIGNAL] =\n"
1467 "\t\tg_signal_new (%s,\n"
1468 "\t\t\tG_TYPE_FROM_CLASS (g_object_class),\n"
1469 "\t\t\t(GSignalFlags)(%s),\n"
1470 "\t\t\tG_STRUCT_OFFSET (%sClass, %s),\n"
1471 "\t\t\tNULL, NULL,\n"
1473 "\t\t\tG_TYPE_%s, %d",
1474 sig, m->signal_name /*m->id* if not given signal_name*/,
1476 typebase, m->id, mar,
1477 (char *)m->gtktypes->data,
1478 is_none ? 0 : g_list_length(m->gtktypes->next));
1486 for(l = m->gtktypes->next; l != NULL; l = l->next) {
1487 char *str = l->data;
1488 if (strncmp (str, "BOXED_", 6) == 0)
1489 t = g_strdup (&(str[6]));
1491 t = g_strconcat ("G_TYPE_", str, NULL);
1492 out_printf (out, ",\n\t\t\t%s", t);
1497 out_printf(out, ");\n");
1499 if(strcmp(m->gtktypes->data, "NONE") != 0 ||
1502 out_printf(out, "\tif ___GOB_UNLIKELY(");
1503 if(strcmp(m->gtktypes->data, "NONE") != 0) {
1504 out_printf(out, "sizeof(");
1505 print_type(out, m->mtype, FALSE);
1506 out_printf(out, "%s",
1508 m->mtype->postfix : "");
1509 out_printf(out, ") != sizeof(%s) || ",
1510 get_cast(m->gtktypes->data, FALSE));
1513 for(al = m->args->next, gl = m->gtktypes->next;
1514 al != NULL && gl != NULL;
1515 al = al->next, gl = gl->next) {
1516 FuncArg *arg = al->data;
1517 char *gtkarg = gl->data;
1519 out_printf(out, "sizeof(");
1520 print_type(out, arg->atype, FALSE);
1521 out_printf(out, "%s",
1522 arg->atype->postfix ?
1523 arg->atype->postfix : "");
1524 out_printf(out, ") != sizeof(%s) || ",
1525 get_cast(gtkarg, FALSE));
1529 "parent_class == NULL /* avoid warning */");
1531 out_printf(out, ") {\n"
1532 "\t\tg_error(\"%s line %d: Type mismatch "
1533 "of \\\"%s\\\" signal signature\");\n"
1535 filename, m->line_no, m->id);
1542 set_def_handlers(Class *c, const char *oname)
1545 gboolean set_line = FALSE;
1547 out_printf(out, "\n");
1548 for(li = c->nodes; li; li = g_list_next(li)) {
1550 Method *m = (Method *)n;
1552 if(n->type != METHOD_NODE ||
1553 (m->method != SIGNAL_FIRST_METHOD &&
1554 m->method != SIGNAL_LAST_METHOD &&
1555 m->method != VIRTUAL_METHOD &&
1556 m->method != OVERRIDE_METHOD))
1559 if(m->line_no > 0 && m->cbuf) {
1560 out_addline_infile(out, m->line_no);
1562 } else if(set_line) {
1563 out_addline_outfile(out);
1568 if (m->method == OVERRIDE_METHOD) {
1570 s = replace_sep (m->otype, '_');
1574 dispose_handler != NULL &&
1575 strcmp (m->id, "dispose") == 0)
1576 out_printf (out, "\tg_object_class->dispose "
1578 else if (need_finalize &&
1580 strcmp(m->id, "finalize") == 0)
1582 "\tg_object_class->finalize = ___finalize;\n");
1583 else if (m->cbuf != NULL)
1585 "\t%s_class->%s = ___%x_%s_%s;\n",
1586 s, m->id, (guint)m->unique_id,
1589 out_printf(out, "\t%s_class->%s = NULL;\n",
1593 out_printf(out, "\t%s->%s = ___real_%s_%s;\n",
1597 out_printf(out, "\t%s->%s = NULL;\n",
1602 out_addline_outfile(out);
1606 make_argument (Argument *a)
1611 char *argflags[] = {
1619 flags = g_string_new ("(GParamFlags)(");
1621 if(a->get && a->set)
1622 g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
1624 g_string_append (flags, "G_PARAM_READABLE");
1626 g_string_append (flags, "G_PARAM_WRITABLE");
1628 g_assert(a->get || a->set);
1630 for (l = a->flags; l != NULL; l = l->next) {
1631 char *flag = l->data;
1633 if(strcmp (flag, "READABLE") == 0 ||
1634 strcmp (flag, "WRITABLE") == 0) {
1635 error_print(GOB_WARN, a->line_no,
1637 "WRITABLE argument flags are "
1638 "set automatically");
1641 for(i = 0; argflags[i]; i++) {
1642 if(strcmp(argflags[i], flag)==0)
1645 g_string_sprintfa(flags, " | %s%s", argflags[i] ? "G_PARAM_" : "", flag);
1648 g_string_append (flags, ")");
1650 s = g_strdup(a->name);
1652 if (!strcmp (a->gtktype, "ENUM"))
1653 out_printf(out, "\tparam_spec = g_param_spec_enum (\"%s\", NULL, NULL,\n"
1654 "\t\tG_TYPE_ENUM, 0,\n"
1656 a->name, flags->str);
1657 if (!strcmp (a->gtktype, "FLAGS"))
1658 out_printf(out, "\tparam_spec = g_param_spec_flags (\"%s\", NULL, NULL,\n"
1659 "\t\tG_TYPE_FLAGS, 0,\n"
1661 a->name, flags->str);
1662 else if (!strcmp (a->gtktype, "OBJECT"))
1663 out_printf(out, "\tparam_spec = g_param_spec_object (\"%s\", NULL, NULL,\n"
1664 "\t\tG_TYPE_OBJECT,\n"
1666 a->name, flags->str);
1667 else if (!strcmp (a->gtktype, "STRING"))
1668 out_printf(out, "\tparam_spec = g_param_spec_string (\"%s\", NULL, NULL,\n"
1671 a->name, flags->str);
1672 else if (!strcmp (a->gtktype, "INT"))
1673 out_printf(out, "\tparam_spec = g_param_spec_int (\"%s\", NULL, NULL,\n"
1674 "\t\tG_MININT, G_MAXINT,\n"
1677 a->name, flags->str);
1678 else if (!strcmp (a->gtktype, "UINT"))
1679 out_printf(out, "\tparam_spec = g_param_spec_uint (\"%s\", NULL, NULL,\n"
1680 "\t\t0, G_MAXUINT,\n"
1683 a->name, flags->str);
1684 else if (!strcmp (a->gtktype, "INT"))
1685 out_printf(out, "\tparam_spec = g_param_spec_int (\"%s\", NULL, NULL,\n"
1686 "\t\tG_MININT, G_MAXINT,\n"
1689 a->name, flags->str);
1690 else if (!strcmp (a->gtktype, "CHAR"))
1691 out_printf(out, "\tparam_spec = g_param_spec_char (\"%s\", NULL, NULL,\n"
1695 a->name, flags->str);
1696 else if (!strcmp (a->gtktype, "UCHAR"))
1697 out_printf(out, "\tparam_spec = g_param_spec_uchar (\"%s\", NULL, NULL,\n"
1701 a->name, flags->str);
1702 else if (!strcmp (a->gtktype, "BOOL") ||
1703 !strcmp (a->gtktype, "BOOLEAN"))
1704 out_printf(out, "\tparam_spec = g_param_spec_boolean (\"%s\", NULL, NULL,\n"
1707 a->name, flags->str);
1708 else if (!strcmp (a->gtktype, "LONG"))
1709 out_printf(out, "\tparam_spec = g_param_spec_long (\"%s\", NULL, NULL,\n"
1710 "\t\tG_MINLONG, G_MAXLONG,\n"
1713 a->name, flags->str);
1714 else if (!strcmp (a->gtktype, "ULONG"))
1715 out_printf(out, "\tparam_spec = g_param_spec_ulong (\"%s\", NULL, NULL,\n"
1716 "\t\t0, G_MAXULONG,\n"
1719 a->name, flags->str);
1720 else if (!strcmp (a->gtktype, "INT64"))
1721 out_printf(out, "\tparam_spec = g_param_spec_int64 (\"%s\", NULL, NULL,\n"
1722 "\t\tG_MININT64, G_MAXINT64,\n"
1725 a->name, flags->str);
1726 else if (!strcmp (a->gtktype, "UINT64"))
1727 out_printf(out, "\tparam_spec = g_param_spec_uint64 (\"%s\", NULL, NULL,\n"
1728 "\t\t0, G_MAXUINT64,\n"
1731 a->name, flags->str);
1732 else if (!strcmp (a->gtktype, "FLOAT"))
1733 out_printf(out, "\tparam_spec = g_param_spec_float (\"%s\", NULL, NULL,\n"
1734 "\t\t-G_MAXFLOAT, G_MAXFLOAT,\n"
1737 a->name, flags->str);
1738 else if (!strcmp (a->gtktype, "DOUBLE"))
1739 out_printf(out, "\tparam_spec = g_param_spec_double (\"%s\", NULL, NULL,\n"
1740 "\t\t-G_MAXDOUBLE, G_MAXDOUBLE,\n"
1743 a->name, flags->str);
1744 else if (!strcmp (a->gtktype, "POINTER"))
1745 out_printf(out, "\tparam_spec = g_param_spec_pointer (\"%s\", NULL, NULL,\n"
1747 a->name, flags->str);
1749 error_printf (GOB_ERROR, a->line_no,
1750 "%s type is not supported for arguments, try using properties",
1753 out_printf(out, "\tg_object_class_install_property (g_object_class,\n"
1754 "\t\tPROP_%s, param_spec);\n", s);
1758 g_string_free(flags, TRUE);
1761 #define value_for_print(str, alt) (str != NULL ? str : alt)
1764 make_property (Property *p)
1768 if (p->get == NULL && p->set == NULL) {
1769 error_print (GOB_ERROR, p->line_no,
1770 "Property has no getter nor setter");
1774 if (p->flags != NULL)
1775 error_print (GOB_WARN, p->line_no,
1776 "Overridden property, flags ignored");
1777 if (p->nick != NULL)
1778 error_print (GOB_WARN, p->line_no,
1779 "Overridden property, nick ignored");
1780 if (p->blurb != NULL)
1781 error_print (GOB_WARN, p->line_no,
1782 "Overridden property, blurb ignored");
1783 if (p->minimum != NULL)
1784 error_print (GOB_WARN, p->line_no,
1785 "Overridden property, minimum ignored");
1786 if (p->maximum != NULL)
1787 error_print (GOB_WARN, p->line_no,
1788 "Overridden property, maximum ignored");
1789 if (p->default_value != NULL)
1790 error_print (GOB_WARN, p->line_no,
1791 "Overridden property, default_value ignored");
1793 s = g_strdup (p->name);
1795 out_printf (out, "\tg_object_class_override_property (g_object_class,\n"
1797 "\t\t\"%s\");\n", s, value_for_print (p->canonical_name, p->name) );
1802 char *argflags[] = {
1810 flags = g_string_new ("(GParamFlags)(");
1812 if (p->get != NULL && p->set != NULL)
1813 g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
1814 else if (p->get != NULL)
1815 g_string_append (flags, "G_PARAM_READABLE");
1817 g_string_append (flags, "G_PARAM_WRITABLE");
1820 for (l = p->flags; l != NULL; l = l->next) {
1821 char *flag = l->data;
1823 if(strcmp (flag, "READABLE") == 0 ||
1824 strcmp (flag, "WRITABLE") == 0) {
1825 error_print(GOB_WARN, p->line_no,
1827 "WRITABLE argument flags are "
1828 "set automatically");
1831 for(i = 0; argflags[i]; i++) {
1832 if(strcmp(argflags[i], flag)==0)
1835 g_string_sprintfa(flags, " | %s%s", argflags[i] ? "G_PARAM_" : "", flag);
1838 g_string_append (flags, ")");
1840 if (strcmp (p->gtktype, "CHAR") == 0) {
1841 out_printf (out, "\tparam_spec = g_param_spec_char\n"
1842 "\t\t(\"%s\" /* name */,\n"
1843 "\t\t %s /* nick */,\n"
1844 "\t\t %s /* blurb */,\n"
1845 "\t\t %s /* minimum */,\n"
1846 "\t\t %s /* maximum */,\n"
1847 "\t\t %s /* default_value */,\n"
1849 value_for_print (p->canonical_name, p->name),
1850 value_for_print (p->nick, "NULL"),
1851 value_for_print (p->blurb, "NULL"),
1852 value_for_print (p->minimum, "-128"),
1853 value_for_print (p->maximum, "127"),
1854 value_for_print (p->default_value, "0"),
1856 } else if (strcmp (p->gtktype, "UCHAR") == 0) {
1857 out_printf (out, "\tparam_spec = g_param_spec_uchar\n"
1858 "\t\t(\"%s\" /* name */,\n"
1859 "\t\t %s /* nick */,\n"
1860 "\t\t %s /* blurb */,\n"
1861 "\t\t %s /* minimum */,\n"
1862 "\t\t %s /* maximum */,\n"
1863 "\t\t %s /* default_value */,\n"
1865 value_for_print (p->canonical_name, p->name),
1866 value_for_print (p->nick, "NULL"),
1867 value_for_print (p->blurb, "NULL"),
1868 value_for_print (p->minimum, "0"),
1869 value_for_print (p->maximum, "0xFF"),
1870 value_for_print (p->default_value, "0"),
1872 } else if (strcmp (p->gtktype, "BOOLEAN") == 0) {
1873 out_printf (out, "\tparam_spec = g_param_spec_boolean\n"
1874 "\t\t(\"%s\" /* name */,\n"
1875 "\t\t %s /* nick */,\n"
1876 "\t\t %s /* blurb */,\n"
1877 "\t\t %s /* default_value */,\n"
1879 value_for_print (p->canonical_name, p->name),
1880 value_for_print (p->nick, "NULL"),
1881 value_for_print (p->blurb, "NULL"),
1882 value_for_print (p->default_value, "FALSE"),
1884 } else if (strcmp (p->gtktype, "INT") == 0) {
1885 out_printf (out, "\tparam_spec = g_param_spec_int\n"
1886 "\t\t(\"%s\" /* name */,\n"
1887 "\t\t %s /* nick */,\n"
1888 "\t\t %s /* blurb */,\n"
1889 "\t\t %s /* minimum */,\n"
1890 "\t\t %s /* maximum */,\n"
1891 "\t\t %s /* default_value */,\n"
1893 value_for_print (p->canonical_name, p->name),
1894 value_for_print (p->nick, "NULL"),
1895 value_for_print (p->blurb, "NULL"),
1896 value_for_print (p->minimum, "G_MININT"),
1897 value_for_print (p->maximum, "G_MAXINT"),
1898 value_for_print (p->default_value, "0"),
1900 } else if (strcmp (p->gtktype, "UINT") == 0) {
1901 out_printf (out, "\tparam_spec = g_param_spec_uint\n"
1902 "\t\t(\"%s\" /* name */,\n"
1903 "\t\t %s /* nick */,\n"
1904 "\t\t %s /* blurb */,\n"
1905 "\t\t %s /* minimum */,\n"
1906 "\t\t %s /* maximum */,\n"
1907 "\t\t %s /* default_value */,\n"
1909 value_for_print (p->canonical_name, p->name),
1910 value_for_print (p->nick, "NULL"),
1911 value_for_print (p->blurb, "NULL"),
1912 value_for_print (p->minimum, "0"),
1913 value_for_print (p->maximum, "G_MAXUINT"),
1914 value_for_print (p->default_value, "0"),
1916 } else if (strcmp (p->gtktype, "LONG") == 0) {
1917 out_printf (out, "\tparam_spec = g_param_spec_long\n"
1918 "\t\t(\"%s\" /* name */,\n"
1919 "\t\t %s /* nick */,\n"
1920 "\t\t %s /* blurb */,\n"
1921 "\t\t %s /* minimum */,\n"
1922 "\t\t %s /* maximum */,\n"
1923 "\t\t %s /* default_value */,\n"
1925 value_for_print (p->canonical_name, p->name),
1926 value_for_print (p->nick, "NULL"),
1927 value_for_print (p->blurb, "NULL"),
1928 value_for_print (p->minimum, "G_MINLONG"),
1929 value_for_print (p->maximum, "G_MAXLONG"),
1930 value_for_print (p->default_value, "0"),
1932 } else if (strcmp (p->gtktype, "ULONG") == 0) {
1933 out_printf (out, "\tparam_spec = g_param_spec_ulong\n"
1934 "\t\t(\"%s\" /* name */,\n"
1935 "\t\t %s /* nick */,\n"
1936 "\t\t %s /* blurb */,\n"
1937 "\t\t %s /* minimum */,\n"
1938 "\t\t %s /* maximum */,\n"
1939 "\t\t %s /* default_value */,\n"
1941 value_for_print (p->canonical_name, p->name),
1942 value_for_print (p->nick, "NULL"),
1943 value_for_print (p->blurb, "NULL"),
1944 value_for_print (p->minimum, "0"),
1945 value_for_print (p->maximum, "G_MAXULONG"),
1946 value_for_print (p->default_value, "0"),
1948 } else if (strcmp (p->gtktype, "INT64") == 0) {
1949 out_printf (out, "\tparam_spec = g_param_spec_int64\n"
1950 "\t\t(\"%s\" /* name */,\n"
1951 "\t\t %s /* nick */,\n"
1952 "\t\t %s /* blurb */,\n"
1953 "\t\t %s /* minimum */,\n"
1954 "\t\t %s /* maximum */,\n"
1955 "\t\t %s /* default_value */,\n"
1957 value_for_print (p->canonical_name, p->name),
1958 value_for_print (p->nick, "NULL"),
1959 value_for_print (p->blurb, "NULL"),
1960 value_for_print (p->minimum, "G_MININT64"),
1961 value_for_print (p->maximum, "G_MAXINT64"),
1962 value_for_print (p->default_value, "0"),
1964 } else if (strcmp (p->gtktype, "UINT64") == 0) {
1965 out_printf (out, "\tparam_spec = g_param_spec_uint64\n"
1966 "\t\t(\"%s\" /* name */,\n"
1967 "\t\t %s /* nick */,\n"
1968 "\t\t %s /* blurb */,\n"
1969 "\t\t %s /* minimum */,\n"
1970 "\t\t %s /* maximum */,\n"
1971 "\t\t %s /* default_value */,\n"
1973 value_for_print (p->canonical_name, p->name),
1974 value_for_print (p->nick, "NULL"),
1975 value_for_print (p->blurb, "NULL"),
1976 value_for_print (p->minimum, "0"),
1977 value_for_print (p->maximum, "G_MAXUINT64"),
1978 value_for_print (p->default_value, "0"),
1980 } else if (strcmp (p->gtktype, "UNICHAR") == 0) {
1981 out_printf (out, "\tparam_spec = g_param_spec_unichar\n"
1982 "\t\t(\"%s\" /* name */,\n"
1983 "\t\t %s /* nick */,\n"
1984 "\t\t %s /* blurb */,\n"
1985 "\t\t %s /* default_value */,\n"
1987 value_for_print (p->canonical_name, p->name),
1988 value_for_print (p->nick, "NULL"),
1989 value_for_print (p->blurb, "NULL"),
1990 value_for_print (p->default_value, "0"),
1992 } else if (strcmp (p->gtktype, "ENUM") == 0) {
1993 char *type = make_me_type (p->extra_gtktype,
1995 out_printf (out, "\tparam_spec = g_param_spec_enum\n"
1996 "\t\t(\"%s\" /* name */,\n"
1997 "\t\t %s /* nick */,\n"
1998 "\t\t %s /* blurb */,\n"
1999 "\t\t %s /* enum_type */,\n"
2000 "\t\t %s /* default_value */,\n"
2002 value_for_print (p->canonical_name, p->name),
2003 value_for_print (p->nick, "NULL"),
2004 value_for_print (p->blurb, "NULL"),
2006 value_for_print (p->default_value, "0"),
2009 } else if (strcmp (p->gtktype, "FLAGS") == 0) {
2010 char *type = make_me_type (p->extra_gtktype,
2012 out_printf (out, "\tparam_spec = g_param_spec_flags\n"
2013 "\t\t(\"%s\" /* name */,\n"
2014 "\t\t %s /* nick */,\n"
2015 "\t\t %s /* blurb */,\n"
2016 "\t\t %s /* flags_type */,\n"
2017 "\t\t %s /* default_value */,\n"
2019 value_for_print (p->canonical_name, p->name),
2020 value_for_print (p->nick, "NULL"),
2021 value_for_print (p->blurb, "NULL"),
2023 value_for_print (p->default_value, "0"),
2026 } else if (strcmp (p->gtktype, "FLOAT") == 0) {
2027 out_printf (out, "\tparam_spec = g_param_spec_float\n"
2028 "\t\t(\"%s\" /* name */,\n"
2029 "\t\t %s /* nick */,\n"
2030 "\t\t %s /* blurb */,\n"
2031 "\t\t %s /* minimum */,\n"
2032 "\t\t %s /* maximum */,\n"
2033 "\t\t %s /* default_value */,\n"
2035 value_for_print (p->canonical_name, p->name),
2036 value_for_print (p->nick, "NULL"),
2037 value_for_print (p->blurb, "NULL"),
2038 value_for_print (p->minimum, "-G_MAXFLOAT"),
2039 value_for_print (p->maximum, "G_MAXFLOAT"),
2040 value_for_print (p->default_value, "0.0"),
2042 } else if (strcmp (p->gtktype, "DOUBLE") == 0) {
2043 out_printf (out, "\tparam_spec = g_param_spec_double\n"
2044 "\t\t(\"%s\" /* name */,\n"
2045 "\t\t %s /* nick */,\n"
2046 "\t\t %s /* blurb */,\n"
2047 "\t\t %s /* minimum */,\n"
2048 "\t\t %s /* maximum */,\n"
2049 "\t\t %s /* default_value */,\n"
2051 value_for_print (p->canonical_name, p->name),
2052 value_for_print (p->nick, "NULL"),
2053 value_for_print (p->blurb, "NULL"),
2054 value_for_print (p->minimum, "-G_MAXDOUBLE"),
2055 value_for_print (p->maximum, "G_MAXDOUBLE"),
2056 value_for_print (p->default_value, "0.0"),
2058 } else if (strcmp (p->gtktype, "STRING") == 0) {
2059 out_printf (out, "\tparam_spec = g_param_spec_string\n"
2060 "\t\t(\"%s\" /* name */,\n"
2061 "\t\t %s /* nick */,\n"
2062 "\t\t %s /* blurb */,\n"
2063 "\t\t %s /* default_value */,\n"
2065 value_for_print (p->canonical_name, p->name),
2066 value_for_print (p->nick, "NULL"),
2067 value_for_print (p->blurb, "NULL"),
2068 value_for_print (p->default_value, "NULL"),
2070 } else if (strcmp (p->gtktype, "PARAM") == 0) {
2071 char *type = make_me_type (p->extra_gtktype,
2073 out_printf (out, "\tparam_spec = g_param_spec_param\n"
2074 "\t\t(\"%s\" /* name */,\n"
2075 "\t\t %s /* nick */,\n"
2076 "\t\t %s /* blurb */,\n"
2077 "\t\t %s /* param_type */,\n"
2079 value_for_print (p->canonical_name, p->name),
2080 value_for_print (p->nick, "NULL"),
2081 value_for_print (p->blurb, "NULL"),
2085 } else if (strcmp (p->gtktype, "BOXED") == 0) {
2086 char *type = make_me_type (p->extra_gtktype,
2088 out_printf (out, "\tparam_spec = g_param_spec_boxed\n"
2089 "\t\t(\"%s\" /* name */,\n"
2090 "\t\t %s /* nick */,\n"
2091 "\t\t %s /* blurb */,\n"
2092 "\t\t %s /* boxed_type */,\n"
2094 value_for_print (p->canonical_name, p->name),
2095 value_for_print (p->nick, "NULL"),
2096 value_for_print (p->blurb, "NULL"),
2100 } else if (strcmp (p->gtktype, "POINTER") == 0) {
2101 out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
2102 "\t\t(\"%s\" /* name */,\n"
2103 "\t\t %s /* nick */,\n"
2104 "\t\t %s /* blurb */,\n"
2106 value_for_print (p->canonical_name, p->name),
2107 value_for_print (p->nick, "NULL"),
2108 value_for_print (p->blurb, "NULL"),
2110 /* FIXME: VALUE_ARRAY */
2111 } else if (strcmp (p->gtktype, "CLOSURE") == 0) {
2112 out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
2113 "\t\t(\"%s\" /* name */,\n"
2114 "\t\t %s /* nick */,\n"
2115 "\t\t %s /* blurb */,\n"
2117 value_for_print (p->canonical_name, p->name),
2118 value_for_print (p->nick, "NULL"),
2119 value_for_print (p->blurb, "NULL"),
2121 } else if (strcmp (p->gtktype, "OBJECT") == 0) {
2122 char *type = make_me_type (p->extra_gtktype,
2124 out_printf (out, "\tparam_spec = g_param_spec_object\n"
2125 "\t\t(\"%s\" /* name */,\n"
2126 "\t\t %s /* nick */,\n"
2127 "\t\t %s /* blurb */,\n"
2128 "\t\t %s /* object_type */,\n"
2130 value_for_print (p->canonical_name, p->name),
2131 value_for_print (p->nick, "NULL"),
2132 value_for_print (p->blurb, "NULL"),
2137 error_printf (GOB_ERROR, p->line_no,
2138 "%s type is not supported by properties",
2142 s = g_strdup (p->name);
2144 out_printf (out, "\tg_object_class_install_property (g_object_class,\n"
2146 "\t\tparam_spec);\n", s);
2149 g_string_free (flags, TRUE);
2154 make_arguments(Class *c)
2157 if (get_properties > 0)
2158 out_printf(out, "\tg_object_class->get_property = ___object_get_property;\n");
2159 if (set_properties > 0)
2160 out_printf(out, "\tg_object_class->set_property = ___object_set_property;\n");
2161 out_printf (out, " {\n");
2162 for (li = c->nodes; li != NULL; li = li->next) {
2164 if ((n->type == PROPERTY_NODE && ! ((Property *) n)->override)
2165 || n->type == ARGUMENT_NODE) {
2166 out_printf(out, "\tGParamSpec *param_spec;\n\n");
2171 for (li = c->nodes; li != NULL; li = li->next) {
2173 if (n->type == PROPERTY_NODE)
2174 make_property ((Property *)n);
2175 else if (n->type == ARGUMENT_NODE)
2176 make_argument ((Argument *)n);
2178 out_printf(out, " }\n");
2182 print_initializer(Method *m, Variable *v)
2189 if(v->initializer == NULL)
2192 if(v->scope == PRIVATE_SCOPE)
2193 root = g_strconcat(((FuncArg *)m->args->data)->name,
2196 root = g_strdup(((FuncArg *)m->args->data)->name);
2198 if(v->initializer_line > 0)
2199 out_addline_infile(out, v->initializer_line);
2201 if (v->initializer_simple)
2202 out_printf(out, "\t%s->%s = %s;\n",
2203 root, v->id, v->initializer);
2204 else if (strcmp(v->id, "_glade_xml") == 0)
2205 /* This is OK, this v->initializer string is set internally
2206 and it will eat exactly one string! */
2207 out_printf(out,v->initializer, ((FuncArg *)m->args->data)->name);
2209 out_printf(out, "%s", v->initializer);
2211 if(v->initializer_line > 0)
2212 out_addline_outfile(out);
2218 print_glade_widget(Method *m, Variable *v)
2223 if(!v->glade_widget)
2226 if(v->scope == PRIVATE_SCOPE)
2227 root = g_strconcat(((FuncArg *)m->args->data)->name,
2230 root = g_strdup(((FuncArg *)m->args->data)->name);
2232 cast = get_type(v->vtype, FALSE);
2233 out_printf(out, "\t%s->%s = (%s)glade_xml_get_widget(%s->_glade_xml, \"%s\");\n",
2234 root, v->id, cast, root, v->id);
2240 print_destructor (Variable *v)
2244 if(v->destructor == NULL)
2247 if(v->scope == PRIVATE_SCOPE)
2248 root = "self->_priv";
2252 if(v->destructor_simple) {
2253 if(v->destructor_line > 0)
2254 out_addline_infile(out, v->destructor_line);
2257 out_printf(out, "\tif(%s->%s) { "
2258 "(reinterpret_cast<void (*)(void *)>(%s)) ((gpointer)%s->%s); "
2259 "%s->%s = NULL; }\n",
2260 root, v->id, v->destructor, root, v->id,
2263 out_printf(out, "\tif(%s->%s) { "
2264 "%s ((gpointer) %s->%s); "
2265 "%s->%s = NULL; }\n",
2266 root, v->id, v->destructor, root, v->id,
2270 if(v->destructor_line > 0)
2271 out_addline_outfile(out);
2273 out_printf(out, "#define %s (%s->%s)\n", v->id, root, v->id);
2274 out_printf(out, "#define VAR %s\n", v->id);
2275 out_printf(out, "\t{\n");
2276 if(v->destructor_line > 0)
2277 out_addline_infile(out, v->destructor_line);
2279 out_printf(out, "\t%s}\n", v->destructor);
2281 if(v->destructor_line > 0)
2282 out_addline_outfile(out);
2283 out_printf(out, "\tmemset(&(%s), 0, sizeof(%s));\n",
2285 out_printf(out, "#undef VAR\n");
2286 out_printf(out, "#undef %s\n", v->id);
2291 add_constructor (Class *c)
2293 out_printf(out, "\nstatic GObject *\n"
2294 "___constructor (GType type, guint n_construct_properties, GObjectConstructParam *construct_properties)\n"
2297 "#define __GOB_FUNCTION__ \"%s::constructor\"\n",
2300 out_printf(out, "\tGObject *obj_self;\n");
2301 out_printf(out, "\t%s *self;\n", typebase);
2303 out_printf(out, "\tobj_self = G_OBJECT_CLASS (parent_class)->constructor (type, n_construct_properties, construct_properties);\n");
2304 out_printf(out, "\tself = %s (obj_self);\n", macrobase);
2306 if (user_constructor->line_no > 0)
2307 out_addline_infile (out, user_constructor->line_no);
2308 out_printf (out, "\t%s_constructor (self);\n", funcbase);
2309 if (user_constructor->line_no > 0)
2310 out_addline_outfile (out);
2312 out_printf(out, "\treturn obj_self;\n");
2313 out_printf(out, "}\n"
2314 "#undef __GOB_FUNCTION__\n\n");
2318 print_unreftors (Class *c)
2321 for(li = ((Class *)class)->nodes;
2325 Variable *v = (Variable *)n;
2326 if (n->type == VARIABLE_NODE &&
2327 v->scope != CLASS_SCOPE &&
2328 v->destructor_unref)
2329 print_destructor (v);
2334 add_dispose (Class *c)
2336 out_printf(out, "\nstatic void\n"
2337 "___dispose (GObject *obj_self)\n"
2340 "#define __GOB_FUNCTION__ \"%s::dispose\"\n",
2343 if (unreftors > 0 || user_dispose_method != NULL) {
2344 out_printf (out, "\t%s *self%s = %s (obj_self);\n",
2346 ! no_gnu ? " G_GNUC_UNUSED" : "",
2350 if (dispose_handler != NULL) {
2351 if (unreftors > 0) {
2352 print_unreftors (c);
2355 /* so we get possible bad argument warning */
2356 if (dispose_handler->line_no > 0)
2357 out_addline_infile (out, dispose_handler->line_no);
2358 out_printf (out, "\t___%x_%s_dispose(obj_self);\n",
2359 (guint)dispose_handler->unique_id, funcbase);
2360 if (dispose_handler->line_no > 0)
2361 out_addline_outfile (out);
2363 if (user_dispose_method != NULL) {
2364 if (user_dispose_method->line_no > 0)
2365 out_addline_infile (out, user_dispose_method->line_no);
2366 out_printf (out, "\t%s_dispose (self);\n", funcbase);
2367 if (user_dispose_method->line_no > 0)
2368 out_addline_outfile (out);
2371 if (unreftors > 0) {
2372 print_unreftors (c);
2376 "\tif (G_OBJECT_CLASS (parent_class)->dispose) \\\n"
2377 "\t\t(* G_OBJECT_CLASS (parent_class)->dispose) (obj_self);\n");
2380 out_printf(out, "}\n"
2381 "#undef __GOB_FUNCTION__\n\n");
2385 print_destructors (Class *c)
2388 for (li = ((Class *)class)->nodes;
2392 Variable *v = (Variable *)n;
2393 if (n->type == VARIABLE_NODE &&
2394 v->scope != CLASS_SCOPE &&
2395 ! v->destructor_unref)
2396 print_destructor (v);
2401 add_finalize (Class *c)
2405 "___finalize(GObject *obj_self)\n"
2408 "#define __GOB_FUNCTION__ \"%s::finalize\"\n",
2413 user_finalize_method != NULL) {
2414 const char *unused = "";
2416 unused = " G_GNUC_UNUSED";
2417 out_printf(out, "\t%s *self%s = %s (obj_self);\n",
2418 typebase, unused, macrobase);
2421 const char *unused = "";
2423 unused = " G_GNUC_UNUSED";
2424 out_printf(out, "\tgpointer priv%s = self->_priv;\n",
2428 if(finalize_handler) {
2429 if (destructors > 0) {
2430 print_destructors (c);
2433 /* so we get possible bad argument warning */
2434 if(finalize_handler->line_no > 0)
2435 out_addline_infile(out, finalize_handler->line_no);
2436 out_printf(out, "\t___%x_%s_finalize(obj_self);\n",
2437 (guint)finalize_handler->unique_id, funcbase);
2438 if(finalize_handler->line_no > 0)
2439 out_addline_outfile(out);
2441 if (user_finalize_method != NULL) {
2442 if (user_finalize_method->line_no > 0)
2443 out_addline_infile (out, user_finalize_method->line_no);
2444 out_printf (out, "\t%s_finalize (self);\n", funcbase);
2445 if (user_finalize_method->line_no > 0)
2446 out_addline_outfile (out);
2449 if (destructors > 0) {
2450 print_destructors (c);
2454 "\tif(G_OBJECT_CLASS(parent_class)->finalize) \\\n"
2455 "\t\t(* G_OBJECT_CLASS(parent_class)->finalize)(obj_self);\n");
2458 out_printf(out, "}\n"
2459 "#undef __GOB_FUNCTION__\n\n");
2463 make_bonobo_object_epv (Class *c, const char *classname)
2466 gboolean added_line = FALSE;
2468 for (li = c->nodes; li != NULL; li = li->next) {
2470 Method *m = (Method *)n;
2471 if(n->type != METHOD_NODE ||
2472 m->method == OVERRIDE_METHOD)
2475 if (m->bonobo_object_func) {
2476 if(m->line_no > 0) {
2477 out_addline_infile(out, m->line_no);
2479 } else if (m->line_no == 0 &&
2481 out_addline_outfile(out);
2484 out_printf (out, "\t%s->_epv.%s = self_%s;\n",
2485 classname, m->id, m->id);
2489 out_addline_outfile(out);
2495 const char *unused = "";
2499 unused = " G_GNUC_UNUSED";
2501 for(li=c->nodes;li;li=g_list_next(li)) {
2505 if(n->type != METHOD_NODE)
2508 if(m->method == INIT_METHOD) {
2510 out_addline_infile(out, m->line_no);
2511 print_method(out, "static ", "\n", "", " ", "", "\n",
2512 m, FALSE, FALSE, FALSE, TRUE, TRUE,
2514 out_printf(out, "{\n");
2516 out_addline_outfile(out);
2518 "#define __GOB_FUNCTION__ \"%s::init\"\n",
2521 out_printf(out, "\t%s->_priv = "
2522 "G_TYPE_INSTANCE_GET_PRIVATE(%s,%s,%sPrivate);\n",
2523 ((FuncArg *)m->args->data)->name,
2524 ((FuncArg *)m->args->data)->name,
2527 } else if(always_private_struct) {
2528 out_printf(out, "\t%s->_priv = NULL;\n",
2529 ((FuncArg *)m->args->data)->name);
2531 if(initializers > 0) {
2533 for(li = ((Class *)class)->nodes;
2537 Variable *v = (Variable *)n;
2538 if(n->type != VARIABLE_NODE ||
2539 v->scope == CLASS_SCOPE)
2541 print_initializer(m, v);
2544 if(glade_widgets > 0) {
2546 for(li = ((Class *)class)->nodes;
2550 Variable *v = (Variable *)n;
2551 if(n->type != VARIABLE_NODE ||
2552 v->scope == CLASS_SCOPE)
2554 print_glade_widget(m, v);
2557 } else if(m->method == CLASS_INIT_METHOD) {
2558 gboolean did_base_obj = FALSE;
2561 out_addline_infile(out, m->line_no);
2562 print_method(out, "static ", "\n", "", " ", "", "\n",
2563 m, FALSE, FALSE, FALSE, TRUE, TRUE,
2565 out_printf(out, "{\n");
2567 out_addline_outfile(out);
2569 "#define __GOB_FUNCTION__ \"%s::class_init\"\n",
2571 if (set_properties > 0 ||
2572 get_properties > 0 ||
2579 "g_object_class%s = "
2580 "(GObjectClass*) %s;\n",
2582 ((FuncArg *)m->args->data)->name);
2583 did_base_obj = TRUE;
2588 ((FuncArg *)m->args->data)->name,
2593 "\n\tg_type_class_add_private(%s,sizeof(%sPrivate));\n",
2594 ((FuncArg *)m->args->data)->name,
2597 if (initializers > 0) {
2599 for(li = ((Class *)class)->nodes;
2603 Variable *v = (Variable *)n;
2604 if(n->type == VARIABLE_NODE &&
2605 v->scope == CLASS_SCOPE)
2606 print_initializer(m, v);
2610 out_printf(out, "\n\tparent_class = ");
2612 out_printf(out, "(%sClass *)", ptypebase);
2613 out_printf(out, "g_type_class_ref (%s);\n",
2619 set_def_handlers(c, ((FuncArg *)m->args->data)->name);
2621 /* if there are no handlers for these things, we
2622 * need to set them up here */
2623 if(need_constructor)
2624 out_printf(out, "\tg_object_class->constructor "
2625 "= ___constructor;\n");
2626 if(need_dispose && !dispose_handler)
2627 out_printf(out, "\tg_object_class->dispose "
2629 if(need_finalize && !finalize_handler)
2630 out_printf(out, "\tg_object_class->finalize = "
2633 if(get_properties > 0 || set_properties > 0)
2636 if (c->bonobo_object_class != NULL) {
2637 make_bonobo_object_epv (c, ((FuncArg *)m->args->data)->name);
2643 out_printf(out, " {\n");
2644 out_addline_infile(out, m->ccode_line);
2645 out_printf(out, "%s\n", m->cbuf);
2646 out_addline_outfile(out);
2647 out_printf(out, " }\n");
2649 out_printf(out, "}\n"
2650 "#undef __GOB_FUNCTION__\n");
2655 add_argument (Argument *a, gboolean is_set)
2659 char *the_type_lower;
2664 line_no = a->set_line;
2667 line_no = a->get_line;
2671 s = g_strdup(a->name);
2673 out_printf(out, "\tcase PROP_%s:\n\t{", s);
2675 the_type_lower = g_strdup (a->gtktype);
2676 gob_strdown (the_type_lower);
2678 /* HACK because there is no g_value_set/get for unichar */
2679 if (strcmp (the_type_lower, "unichar") == 0) {
2680 g_free (the_type_lower);
2681 the_type_lower = g_strdup ("uint");
2686 const char *unused = "";
2688 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
2689 unused = " G_GNUC_UNUSED";
2692 if (a->atype != NULL &&
2693 /* gcc -Wbad-function-cast is wanking stupid, moronic
2694 and otherwise evil so we should just use a (gint)
2695 or (guint) cast, not the specific type cast */
2697 (strcmp (a->gtktype, "ENUM") != 0 &&
2698 strcmp (a->gtktype, "FLAGS") != 0)))
2699 cast = get_type (a->atype, TRUE);
2701 cast = g_strdup (get_cast (a->gtktype, FALSE));
2703 out_printf (out, "\t%s ARG%s = (%s) g_value_get_%s (VAL);\n",
2704 cast, unused, cast, the_type_lower);
2707 } else if ( ! is_set) {
2710 if (a->atype != NULL)
2711 cast = get_type (a->atype, TRUE);
2713 cast = g_strdup (get_cast (a->gtktype, FALSE));
2714 out_printf (out, "\t%s ARG;\n"
2715 "\tmemset (&ARG, 0, sizeof (%s));\n",
2721 out_printf(out, "\t\t{\n");
2723 out_addline_infile (out, line_no);
2724 out_printf (out, "%s\n", cbuf);
2726 out_addline_outfile (out);
2727 out_printf (out, "\t\t}\n");
2729 if (strcmp (a->gtktype, "OBJECT") == 0)
2730 out_printf (out, "\t\tg_value_set_%s (VAL, G_OBJECT (ARG));\n",
2733 out_printf (out, "\t\t"
2734 "g_value_set_%s (VAL, ARG);\n",
2737 g_free (the_type_lower);
2740 (no_gnu || for_cpp /* g++ has a cow with G_GNUC_UNUSED */)) {
2741 out_printf (out, "\t\tif (&ARG) break;\n");
2744 out_printf (out, "\t\tbreak;\n");
2746 out_printf (out, "\t}\n");
2750 add_property (Property *p, gboolean is_set)
2753 char *the_type_lower;
2759 line_no = p->set_line;
2762 line_no = p->get_line;
2767 name_upper = g_strdup (p->name);
2768 gob_strup (name_upper);
2769 the_type_lower = g_strdup (p->gtktype);
2770 gob_strdown (the_type_lower);
2772 out_printf (out, "\tcase PROP_%s:\n", name_upper);
2774 out_printf(out, "\t\t{\n");
2776 out_addline_infile (out, line_no);
2777 out_printf (out, "%s\n", cbuf);
2779 out_addline_outfile (out);
2780 out_printf (out, "\t\t}\n");
2782 g_free (name_upper);
2783 g_free (the_type_lower);
2785 out_printf (out, "\t\tbreak;\n");
2789 add_getset_arg(Class *c, gboolean is_set)
2792 const char *unused = "";
2793 const char *hack_unused = "";
2795 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
2796 unused = " G_GNUC_UNUSED";
2798 hack_unused = "if (&VAL || &pspec) break;\n\t\t";
2801 out_printf(out, "\nstatic void\n"
2802 "___object_%s_property (GObject *object,\n"
2803 "\tguint property_id,\n"
2804 "\t%sGValue *VAL%s,\n"
2805 "\tGParamSpec *pspec%s)\n"
2806 "#define __GOB_FUNCTION__ \"%s::%s_property\"\n"
2809 "\tself = %s (object);\n\n"
2810 "\tswitch (property_id) {\n",
2811 is_set ? "set" : "get",
2812 is_set ? "const " : "",
2816 is_set ? "set" : "get",
2821 for (li = c->nodes; li != NULL; li = li->next) {
2823 if (n->type == PROPERTY_NODE)
2824 add_property ((Property *)n, is_set);
2825 else if (n->type == ARGUMENT_NODE)
2826 add_argument ((Argument *)n, is_set);
2828 out_printf (out, "\tdefault:\n"
2829 "/* Apparently in g++ this is needed, glib is b0rk */\n"
2830 "#ifndef __PRETTY_FUNCTION__\n"
2831 "# undef G_STRLOC\n"
2832 "# define G_STRLOC __FILE__ \":\" G_STRINGIFY (__LINE__)\n"
2834 "\t\tG_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);\n"
2835 "\t\t%sbreak;\n\t}\n"
2837 "#undef __GOB_FUNCTION__\n", hack_unused);
2841 print_checks (Method *m, FuncArg *fa)
2845 gboolean checked_null = FALSE;
2846 is_void = (strcmp(m->mtype->name, "void")==0 &&
2847 m->mtype->pointer == NULL);
2849 for(li = fa->checks; li != NULL; li = li->next) {
2850 Check *ch = li->data;
2852 /* point to the method prot in .gob for failed checks */
2854 out_addline_infile(out, m->line_no);
2856 out_printf(out, "\tg_return_if_fail (");
2858 out_printf(out, "\tg_return_val_if_fail (");
2859 switch(ch->chtype) {
2861 out_printf(out, "%s != NULL", fa->name);
2862 checked_null = TRUE;
2865 s = make_pre_macro(fa->atype->name, "IS");
2867 out_printf(out, "%s (%s)", s, fa->name);
2869 /* if not check null, null may be valid */
2870 out_printf(out, "!(%s) || %s (%s)", fa->name,
2875 out_printf(out, "%s < %s", fa->name, ch->number);
2878 out_printf(out, "%s > %s", fa->name, ch->number);
2881 out_printf(out, "%s <= %s", fa->name, ch->number);
2884 out_printf(out, "%s >= %s", fa->name, ch->number);
2887 out_printf(out, "%s == %s", fa->name, ch->number);
2890 out_printf(out, "%s != %s", fa->name, ch->number);
2894 out_printf(out, ");\n");
2896 out_printf(out, ", (");
2897 print_type(out, m->mtype, TRUE);
2898 out_printf(out, ")%s);\n",
2899 m->onerror?m->onerror:"0");
2905 print_preconditions(Method *m)
2909 for(li=m->args;li;li=g_list_next(li)) {
2910 FuncArg *fa = li->data;
2912 print_checks(m, fa);
2915 out_addline_outfile(out);
2919 print_method_body (Method *m, gboolean pre, gboolean unused_self)
2921 out_printf(out, "{\n");
2923 out_addline_outfile(out);
2924 out_printf(out, "#define __GOB_FUNCTION__ \"%s::%s\"\n",
2925 ((Class *)class)->otype,
2928 print_preconditions(m);
2932 (no_gnu || for_cpp) &&
2934 ((FuncArg *)(m->args->data))->name != NULL &&
2935 strcmp (((FuncArg *)(m->args->data))->name, "self") == 0) {
2936 out_printf (out, "\tif (&self) { ; }\n");
2939 /* Note: the trailing }'s are on one line, this is so
2940 that we get the no return warning correctly and point to
2941 the correct line in the .gob file, yes this is slightly
2942 ugly in the .c file, but that is not supposed to be
2943 human readable anyway. */
2945 out_printf(out, "{\n");
2947 out_addline_infile(out, m->ccode_line);
2948 out_printf(out, "\t%s}", m->cbuf);
2951 /* Note, there is no \n between the last } and this } so that
2952 * errors/warnings reported on the end of the body get pointed to the
2953 * right line in the .gob source */
2954 out_printf(out, "}\n");
2957 out_addline_outfile(out);
2958 out_printf(out, "#undef __GOB_FUNCTION__\n");
2962 put_signal_args (Method *m)
2968 if (m->args->next == NULL)
2971 for (ali = m->gtktypes->next, li = m->args->next, i = 1;
2972 li != NULL && ali != NULL;
2973 li = li->next, ali = ali->next, i++) {
2974 FuncArg *fa = li->data;
2975 char *str = ali->data;
2976 char *cast = g_strdup (get_cast (str, FALSE));
2977 /* FIXME: This code is so fucking ugly it hurts */
2978 gboolean do_static =
2979 (strcmp (str, "STRING") == 0 ||
2980 strcmp (str, "BOXED") == 0 ||
2981 strncmp (str, "BOXED_", 6) == 0);
2986 cast = get_type (fa->atype, TRUE);
2988 /* we should have already proved before that
2989 the we know all the types */
2990 g_assert (cast != NULL);
2992 if (strncmp (str, "BOXED_", 6) == 0)
2993 t = g_strdup (&(str[6]));
2995 t = g_strconcat ("G_TYPE_", str, NULL);
2998 "\t___param_values[%d].g_type = 0;\n"
2999 "\tg_value_init (&___param_values[%d], %s);\n",
3003 if (strcmp (str, "UNICHAR") == 0)
3004 /* hack because glib is braindamaged */
3005 set_func = g_strdup ("g_value_set_uint");
3006 else if (strncmp (str, "BOXED_", 6) == 0)
3007 set_func = g_strdup ("g_value_set_static_boxed");
3009 set_func = g_strdup_printf ("g_value_set%s_%s",
3010 do_static ? "_static" : "",
3012 gob_strdown (set_func);
3014 out_printf (out, "\t%s (&___param_values[%d], (%s) %s);\n\n",
3015 set_func, i, cast, fa->name);
3023 clear_signal_args (Method *m)
3028 out_printf (out, "\n\tg_value_unset (&___param_values[0]);\n");
3030 if (m->args->next == NULL)
3033 for (li = m->args->next, i = 1;
3035 li = li->next, i++) {
3037 "\tg_value_unset (&___param_values[%d]);\n", i);
3042 get_arg_names_for_macro (Method *m)
3046 GString *gs = g_string_new(NULL);
3048 for(li=m->args;li;li=g_list_next(li)) {
3049 FuncArg *arg = li->data;
3050 g_string_sprintfa (gs, "%s___%s", sep, arg->name);
3053 return g_string_free (gs, FALSE);
3057 put_method(Method *m)
3059 char *s, *args, *doc;
3061 is_void = (strcmp(m->mtype->name, "void")==0 &&
3062 m->mtype->pointer == NULL);
3063 out_printf(out, "\n");
3064 if(m->method != OVERRIDE_METHOD) {
3065 doc = get_gtk_doc(m->id);
3067 out_printf(out, "%s", doc);
3072 case REGULAR_METHOD:
3074 out_addline_infile(out, m->line_no);
3075 if(m->scope == PRIVATE_SCOPE)
3076 print_method(out, "static ", "\n", "", " ", "", "\n",
3077 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3078 else /* PUBLIC, PROTECTED */
3079 print_method(out, "", "\n", "", " ", "", "\n",
3080 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3081 print_method_body(m, TRUE, TRUE);
3082 /* the outfile line was added above */
3084 case SIGNAL_FIRST_METHOD:
3085 case SIGNAL_LAST_METHOD:
3087 out_addline_infile(out, m->line_no);
3088 if(m->scope == PRIVATE_SCOPE)
3089 print_method(out, "static ", "\n", "", " ", "", "\n",
3090 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3091 else /* PUBLIC, PROTECTED */
3092 print_method(out, "", "\n", "", " ", "", "\n",
3093 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3094 out_printf (out, "{\n");
3096 out_addline_outfile (out);
3099 "\tGValue ___param_values[%d];\n"
3100 "\tGValue ___return_val;\n\n"
3101 "memset (&___return_val, 0, "
3102 "sizeof (___return_val));\n"
3103 "memset (&___param_values, 0, "
3104 "sizeof (___param_values));\n\n",
3105 g_list_length (m->args));
3107 print_preconditions (m);
3110 "\n\t___param_values[0].g_type = 0;\n"
3111 "\tg_value_init (&___param_values[0], G_TYPE_FROM_INSTANCE (%s));\n"
3112 "\tg_value_set_instance (&___param_values[0], (gpointer) %s);\n\n",
3113 ((FuncArg *)m->args->data)->name,
3114 ((FuncArg *)m->args->data)->name);
3116 put_signal_args (m);
3118 if (strcmp (m->gtktypes->data, "NONE") != 0) {
3119 const char *defret = NULL;
3121 out_printf (out, "\tg_value_init (&___return_val, G_TYPE_%s);\n",
3122 (char *)m->gtktypes->data);
3124 if (m->defreturn != NULL)
3125 defret = m->defreturn;
3126 else if (m->onerror != NULL)
3127 defret = m->onerror;
3129 if (defret != NULL) {
3131 /* FIXME: This code is so fucking ugly it hurts */
3132 gboolean do_static =
3133 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
3134 strcmp ((char *)m->gtktypes->data, "BOXED") == 0);
3135 char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
3137 cast = get_type (m->mtype, TRUE);
3139 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
3140 /* hack because glib is braindamaged */
3141 set_func = g_strdup ("g_value_set_uint");
3143 set_func = g_strdup_printf ("g_value_set%s_%s",
3144 do_static ? "_static" : "",
3145 (char *)m->gtktypes->data);
3146 gob_strdown (set_func);
3148 out_printf (out, "\t%s (&___return_val, (%s) (%s));\n",
3149 set_func, cast, defret);
3154 out_printf (out, "\n");
3157 s = g_strdup (m->id);
3160 out_printf(out, "\tg_signal_emitv (___param_values,\n"
3161 "\t\tobject_signals[%s_SIGNAL],\n"
3162 "\t\t0 /* detail */,\n"
3163 "\t\t&___return_val);\n", s);
3167 clear_signal_args (m);
3169 if (strcmp (m->gtktypes->data, "NONE") != 0) {
3170 char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
3172 /* Hack because glib is very very braindead */
3174 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
3175 strcmp ((char *)m->gtktypes->data, "BOXED") == 0 ||
3176 strcmp ((char *)m->gtktypes->data, "OBJECT") == 0 ||
3177 strcmp ((char *)m->gtktypes->data, "PARAM") == 0);
3179 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
3180 /* hack because glib is braindamaged */
3181 getfunc = g_strdup ("g_value_get_uint");
3183 getfunc = g_strdup_printf ("g_value_%s_%s",
3184 do_dup ? "dup" : "get",
3185 (char *)m->gtktypes->data);
3186 gob_strdown (getfunc);
3189 cast = get_type (m->mtype, TRUE);
3194 print_type (out, m->mtype, TRUE);
3196 " ___ret = (%s) %s (&___return_val);\n"
3197 "\t\tg_value_unset (&___return_val);\n"
3198 "\t\treturn ___ret;\n"
3205 out_printf(out, "}\n");
3210 out_addline_infile(out, m->line_no);
3211 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
3212 m, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE);
3213 print_method_body(m, FALSE, TRUE);
3214 /* the outfile line was added above */
3216 case VIRTUAL_METHOD:
3218 out_addline_infile(out, m->line_no);
3219 if(m->scope==PRIVATE_SCOPE)
3220 print_method(out, "static ", "\n", "", " ", "", "\n",
3221 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3222 else /* PUBLIC, PROTECTED */
3223 print_method(out, "", "\n", "", " ", "", "\n",
3224 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3225 out_printf(out, "{\n");
3226 out_addline_outfile(out);
3227 out_printf(out, "\t%sClass *klass;\n", typebase);
3228 print_preconditions(m);
3229 out_printf(out, "\tklass = %s_GET_CLASS(%s);\n\n"
3230 "\tif(klass->%s)\n",
3231 macrobase, ((FuncArg *)m->args->data)->name,
3233 if(strcmp(m->mtype->name, "void") == 0 &&
3234 m->mtype->pointer == NULL) {
3236 out_printf(out, "\t\t(*klass->%s)(%s",
3238 ((FuncArg *)m->args->data)->name);
3239 for(li=m->args->next;li;li=g_list_next(li)) {
3240 FuncArg *fa = li->data;
3241 out_printf(out, ",%s", fa->name);
3243 out_printf(out, ");\n}\n");
3246 out_printf(out, "\t\treturn (*klass->%s)(%s",
3248 ((FuncArg *)m->args->data)->name);
3249 for(li=m->args->next;li;li=g_list_next(li)) {
3250 FuncArg *fa = li->data;
3251 out_printf(out, ",%s", fa->name);
3253 out_printf(out, ");\n"
3256 print_type(out, m->mtype, TRUE);
3258 out_printf(out, ")(%s);\n}\n", m->defreturn);
3260 out_printf(out, ")(%s);\n}\n", m->onerror);
3262 out_printf(out, ")(0);\n}\n");
3268 out_addline_infile(out, m->line_no);
3269 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
3270 m, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE);
3271 print_method_body(m, FALSE, TRUE);
3272 /* the outfile line was added above */
3274 case OVERRIDE_METHOD:
3278 out_addline_infile(out, m->line_no);
3279 s = g_strdup_printf("\n___%x_", (guint)m->unique_id);
3280 print_method(out, "static ", s, "", " ", "", "\n",
3281 m, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE);
3283 out_addline_outfile(out);
3284 s = replace_sep(m->otype, '_');
3286 args = get_arg_names_for_macro(m);
3288 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
3289 "\t{ if(%s_CLASS(parent_class)->%s) \\\n"
3290 "\t\t(* %s_CLASS(parent_class)->%s)(%s); }\n",
3291 args, s, m->id, s, m->id, args);
3293 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
3294 "\t((%s_CLASS(parent_class)->%s)? \\\n"
3295 "\t\t(* %s_CLASS(parent_class)->%s)(%s): \\\n"
3297 args, s, m->id, s, m->id, args);
3298 out_printf(out, "(");
3299 print_type(out, m->mtype, TRUE);
3300 out_printf(out, ")%s))\n",
3301 m->onerror?m->onerror:"0");
3305 print_method_body(m, TRUE, TRUE);
3306 /* the outfile line was added above */
3307 out_printf(out, "#undef PARENT_HANDLER\n");
3309 case CONSTRUCTOR_METHOD:
3310 case DISPOSE_METHOD:
3311 case FINALIZE_METHOD:
3313 out_addline_infile(out, m->line_no);
3314 print_method(out, "static ", "\n", "", " ", "", "\n",
3315 m, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE);
3316 print_method_body(m, TRUE, TRUE);
3317 /* the outfile line was added above */
3326 char *outfile, *outfileh, *outfileph;
3328 outfilebase = g_strconcat (fullfilebase, for_cpp ? ".cc" : ".c", NULL);
3329 outfile = g_strconcat(outfilebase, no_touch ? "#gob#" : "", NULL);
3331 outfilehbase = g_strconcat (fullfilebase, ".h", NULL);
3332 outfileh = g_strconcat(outfilehbase, no_touch_headers ? "#gob#" : "", NULL);
3334 if ((privates > 0 || protecteds > 0 ||
3335 private_header == PRIVATE_HEADER_ALWAYS) &&
3336 private_header != PRIVATE_HEADER_NEVER) {
3337 char sep[2] = {0,0};
3340 outfilephbase = g_strconcat (fullfilebase, sep, "private.h", NULL);
3341 outfileph = g_strconcat (outfilephbase, no_touch ? "#gob#" : "", NULL);
3343 outfilephbase = NULL;
3349 out = fopen (outfile, "w");
3351 error_printf (GOB_ERROR, 0,
3352 "Cannot open outfile: %s", outfile);
3354 outh = fopen (outfileh, "w");
3356 error_printf (GOB_ERROR, 0,
3357 "Cannot open outfile: %s", outfileh);
3359 if (outfileph != NULL) {
3360 outph = fopen (outfileph, "w");
3361 if (outph == NULL) {
3362 error_printf (GOB_ERROR, 0,
3363 "Cannot open outfile: %s",
3371 put_argument_nongnu_wrappers (Class *c)
3375 if (get_properties < 0 && set_properties < 0)
3378 for (li = c->nodes; li != NULL; li = li->next) {
3380 const char *name, *gtktype;
3386 if (n->type == ARGUMENT_NODE) {
3387 Argument *a = (Argument *)n;
3389 gtktype = a->gtktype;
3391 get = a->get != NULL;
3392 set = a->set != NULL;
3393 } else if (n->type == PROPERTY_NODE) {
3394 Property *p = (Property *)n;
3396 gtktype = p->gtktype;
3398 get = p->get != NULL;
3399 set = p->set != NULL;
3404 aname = g_strdup (name);
3408 cast = get_type (atype, TRUE);
3410 cast = g_strdup (get_cast (gtktype, TRUE));
3414 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3415 "\"%s\",(%s)(arg)\n",
3416 macrobase, aname, name, cast);
3418 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3419 "\"%s\",(%s*)(arg)\n",
3420 macrobase, aname, name, cast);
3423 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3425 macrobase, aname, name);
3427 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3429 macrobase, aname, name);
3437 put_argument_gnu_wrappers(Class *c)
3441 if(get_properties < 0 && set_properties < 0)
3444 for (li = c->nodes; li != NULL; li = li->next) {
3446 const char *name, *gtktype;
3452 if (n->type == ARGUMENT_NODE) {
3453 Argument *a = (Argument *)n;
3455 gtktype = a->gtktype;
3457 get = a->get != NULL;
3458 set = a->set != NULL;
3459 } else if (n->type == PROPERTY_NODE) {
3460 Property *p = (Property *)n;
3462 gtktype = p->gtktype;
3464 get = p->get != NULL;
3465 set = p->set != NULL;
3470 aname = g_strdup (name);
3474 cast = get_type (atype, TRUE);
3476 cast = g_strdup (get_cast (gtktype, TRUE));
3480 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3481 "\"%s\", __extension__ ({%sz = (arg); z;})\n",
3482 macrobase, aname, name, cast);
3484 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3485 "\"%s\", __extension__ ({%s*z = (arg); z;})\n",
3486 macrobase, aname, name, cast);
3489 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3491 macrobase, aname, name);
3493 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3495 macrobase, aname, name);
3503 print_ccode_block(CCode *cc)
3506 switch(cc->cctype) {
3508 /* HT code is printed exactly like normal header
3509 code but is printed before */
3512 out_printf(fp, "\n");
3515 /* AT code is printed exactly like normal 'all'
3516 code but is printed before */
3519 out_printf(outph, "\n");
3520 out_printf(outph, "%s\n", cc->cbuf);
3521 out_addline_infile(outph, cc->line_no);
3522 out_addline_outfile(outph);
3524 out_printf(outh, "\n");
3525 out_printf(outh, "%s\n", cc->cbuf);
3527 out_printf(fp, "\n");
3528 out_addline_infile(fp, cc->line_no);
3534 out_printf(fp, "\n");
3535 out_addline_infile(fp, cc->line_no);
3542 out_printf(fp, "\n");
3543 out_addline_infile(fp, cc->line_no);
3546 out_printf(fp, "%s\n", cc->cbuf);
3547 if(cc->cctype == C_CCODE ||
3548 cc->cctype == AD_CCODE ||
3549 cc->cctype == A_CCODE ||
3550 cc->cctype == AT_CCODE ||
3551 cc->cctype == PH_CCODE)
3552 out_addline_outfile(fp);
3556 print_class_block(Class *c)
3560 gboolean printed_private = FALSE;
3564 out_printf(outph ? outph : outh, "#include <gtk/gtk.h>\n");
3565 out_printf(outph ? outph : outh, "#include <glade/glade-xml.h>\n\n");
3569 out_printf(out, "/* utility types we may need */\n");
3570 if(special_array[SPECIAL_2POINTER])
3571 out_printf(out, "typedef struct { "
3572 "gpointer a; gpointer b; "
3573 "} ___twopointertype;\n");
3574 if(special_array[SPECIAL_3POINTER])
3575 out_printf(out, "typedef struct { "
3576 "gpointer a; gpointer b; "
3578 "} ___threepointertype;\n");
3579 if(special_array[SPECIAL_INT_POINTER])
3580 out_printf(out, "typedef struct { "
3581 "gint a; gpointer b; "
3582 "} ___intpointertype;\n");
3583 out_printf(out, "\n");
3586 out_printf(outh, "\n/*\n"
3587 " * Type checking and casting macros\n"
3589 out_printf(outh, "#define %s\t"
3590 "(%s_get_type())\n",
3591 macrotype, funcbase);
3592 out_printf(outh, "#define %s(obj)\t"
3593 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s)\n",
3594 macrobase, funcbase, typebase);
3595 out_printf(outh, "#define %s_CONST(obj)\t"
3596 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s const)\n",
3597 macrobase, funcbase, typebase);
3598 out_printf(outh, "#define %s_CLASS(klass)\t"
3599 "G_TYPE_CHECK_CLASS_CAST((klass), %s_get_type(), %sClass)\n",
3600 macrobase, funcbase, typebase);
3601 out_printf(outh, "#define %s(obj)\t"
3602 "G_TYPE_CHECK_INSTANCE_TYPE((obj), %s_get_type ())\n\n",
3605 "#define %s_GET_CLASS(obj)\t"
3606 "G_TYPE_INSTANCE_GET_CLASS((obj), %s_get_type(), %sClass)\n",
3607 macrobase, funcbase, typebase);
3609 if ( ! no_self_alias) {
3610 out_printf(out, "/* self casting macros */\n");
3611 out_printf(out, "#define SELF(x) %s(x)\n", macrobase);
3612 out_printf(out, "#define SELF_CONST(x) %s_CONST(x)\n", macrobase);
3613 out_printf(out, "#define IS_SELF(x) %s(x)\n", macrois);
3614 out_printf(out, "#define TYPE_SELF %s\n", macrotype);
3615 out_printf(out, "#define SELF_CLASS(x) %s_CLASS(x)\n\n",
3617 out_printf(out, "#define SELF_GET_CLASS(x) %s_GET_CLASS(x)\n\n",
3620 out_printf(out, "/* self typedefs */\n");
3621 out_printf(out, "typedef %s Self;\n", typebase);
3622 out_printf(out, "typedef %sClass SelfClass;\n\n", typebase);
3626 always_private_struct) {
3627 out_printf (outh, "\n/* Private structure type */\n");
3628 out_printf (outh, "typedef struct _%sPrivate %sPrivate;\n",
3629 typebase, typebase);
3631 out_printf (outh, "/* There are no privates, this "
3632 "structure is thus never defined */\n");
3635 out_printf (outh, "\n/*\n"
3636 " * Main object structure\n"
3638 s = replace_sep (c->otype, '_');
3640 out_printf (outh, "#ifndef __TYPEDEF_%s__\n"
3641 "#define __TYPEDEF_%s__\n", s, s);
3643 out_printf (outh, "typedef struct _%s %s;\n"
3644 "#endif\n", typebase, typebase);
3645 out_printf (outh, "struct _%s {\n\t%s __parent__;\n",
3646 typebase, ptypebase);
3647 for (li = c->nodes; li; li=li->next) {
3648 static gboolean printed_public = FALSE;
3650 Variable *v = (Variable *)n;
3651 if(n->type == VARIABLE_NODE &&
3652 v->scope == PUBLIC_SCOPE) {
3653 if( ! printed_public) {
3654 out_printf(outh, "\t/*< public >*/\n");
3655 printed_public = TRUE;
3657 put_variable((Variable *)n, outh);
3660 /* put protecteds always AFTER publics */
3661 for (li = c->nodes; li != NULL; li = li->next) {
3663 Variable *v = (Variable *)n;
3664 if (n->type == VARIABLE_NODE &&
3665 v->scope == PROTECTED_SCOPE) {
3666 if ( ! printed_private) {
3667 out_printf (outh, "\t/*< private >*/\n");
3668 printed_private = TRUE;
3670 put_variable ((Variable *)n, outh);
3674 always_private_struct) {
3675 if ( ! printed_private)
3676 out_printf (outh, "\t/*< private >*/\n");
3677 out_printf (outh, "\t%sPrivate *_priv;\n", typebase);
3679 out_printf (outh, "};\n");
3684 /* if we are to stick this into the private
3685 header, if not stick it directly into the
3692 out_printf (outfp, "struct _%sPrivate {\n",
3696 for(li=c->nodes; li; li=li->next) {
3698 Variable *v = (Variable *)n;
3699 if(n->type == VARIABLE_NODE &&
3700 v->scope == PRIVATE_SCOPE) {
3701 out_addline_infile(outfp, v->line_no);
3702 put_variable(v, outfp);
3705 out_addline_outfile(outfp);
3707 out_printf(outfp, "};\n");
3710 out_printf(outh, "\n/*\n"
3711 " * Class definition\n"
3713 out_printf(outh, "typedef struct _%sClass %sClass;\n",
3714 typebase, typebase);
3716 "struct _%sClass {\n\t%sClass __parent__;\n",
3717 typebase, ptypebase);
3718 for(li = c->nodes; li != NULL; li = li->next) {
3720 if(n->type == METHOD_NODE)
3721 put_vs_method((Method *)n);
3723 /* If BonoboX type class put down the epv */
3724 if (c->bonobo_object_class != NULL) {
3726 "\t/* Bonobo object epv */\n"
3727 "\tPOA_%s__epv _epv;\n",
3728 c->bonobo_object_class);
3730 /* put class scope variables */
3731 for (li = c->nodes; li != NULL; li = li->next) {
3733 Variable *v = (Variable *)n;
3734 if (n->type == VARIABLE_NODE &&
3735 v->scope == CLASS_SCOPE)
3736 put_variable ((Variable *)n, outh);
3738 out_printf (outh, "};\n\n");
3740 out_printf (out, "/* here are local prototypes */\n");
3741 if (set_properties > 0) {
3742 out_printf (out, "static void ___object_set_property "
3743 "(GObject *object, guint property_id, "
3744 "const GValue *value, GParamSpec *pspec);\n");
3746 if (get_properties > 0) {
3747 out_printf (out, "static void ___object_get_property "
3748 "(GObject *object, guint property_id, "
3749 "GValue *value, GParamSpec *pspec);\n");
3752 out_printf (outh, "\n/*\n"
3753 " * Public methods\n"
3756 if (!overrode_get_type) {
3758 * For ordinary "static" types it should be safe to mark the
3759 * get_type implementation as const, since the get_type
3760 * function return really is constant at the call boundary
3761 * (even though there is an initial setup on the first call).
3762 * But for dynamic types, since the registration is explicitly
3763 * separated, we need to settle for "pure" as the results of
3764 * get_type differ before and after type registration.
3766 out_printf(outh, "GType\t%s_get_type\t(void) %s;\n", funcbase,
3767 c->dynamic ? "G_GNUC_PURE" : "G_GNUC_CONST");
3771 out_printf(outh, "void\t%s_register_type\t(GTypeModule *);\n",
3775 for(li = c->nodes; li != NULL; li = li->next) {
3777 if(n->type == METHOD_NODE) {
3778 put_pub_method((Method *)n);
3779 put_prot_method((Method *)n);
3780 put_priv_method_prot((Method *)n);
3784 /* this idea is less and less apealing to me */
3786 out_printf (outh, "\n/*\n"
3787 " * Signal connection wrapper macros\n"
3790 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3791 put_signal_macros (c, TRUE);
3792 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3793 put_signal_macros (c, FALSE);
3794 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n");
3796 put_signal_macros (c, FALSE);
3797 out_printf(outh, "\n");
3800 out_printf (out, "\n/*\n"
3801 " * Signal connection wrapper macro shortcuts\n"
3803 put_local_signal_macros (c);
3804 out_printf(outh, "\n");
3807 /* argument wrapping macros */
3808 if(get_properties > 0 || set_properties > 0) {
3809 out_printf(outh, "\n/*\n"
3810 " * Argument wrapping macros\n"
3813 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3814 put_argument_gnu_wrappers(c);
3815 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3816 put_argument_nongnu_wrappers(c);
3817 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n");
3819 put_argument_nongnu_wrappers(c);
3824 for(li = c->nodes; li != NULL; li = li->next) {
3826 if(n->type == METHOD_NODE)
3827 add_signal_prots((Method *)n);
3833 if(any_method_to_alias(c)) {
3834 out_printf (out, "/* Short form macros */\n");
3835 make_method_aliases (c);
3838 add_interface_inits (c);
3840 if (!overrode_get_type) {
3841 if (c->bonobo_object_class != NULL)
3842 add_bonobo_object_get_type();
3843 else if (c->dynamic)
3844 add_dynamic_get_type();
3849 out_printf (out, "/* a macro for creating a new object of our type */\n");
3851 "#define GET_NEW ((%s *)g_object_new(%s_get_type(), NULL))\n\n",
3852 typebase, funcbase);
3854 out_printf (out, "/* a function for creating a new object of our type */\n");
3855 out_printf (out, "#include <stdarg.h>\n");
3857 "static %s * GET_NEW_VARG (const char *first, ...)%s;\n"
3858 "static %s *\nGET_NEW_VARG (const char *first, ...)\n"
3859 "{\n\t%s *ret;\n\tva_list ap;\n"
3860 "\tva_start (ap, first);\n"
3861 "\tret = (%s *)g_object_new_valist (%s_get_type (), "
3864 "\treturn ret;\n}\n\n",
3866 no_gnu ? "" : " G_GNUC_UNUSED",
3867 typebase, typebase, typebase, funcbase);
3871 out_printf (out, "/* a function to connect glade callback */\n");
3872 out_printf (out,"static void\n"
3873 "___glade_xml_connect_foreach(const gchar *handler_name,\n"
3874 "GObject *object,\n"
3875 "const gchar *signal_name,\n"
3876 "const gchar *signal_data,\n"
3877 "GObject *connect_object,\n"
3879 "gpointer user_data)\n"
3881 "\tstatic GModule * allsymbols = NULL;\n"
3883 "\tif (!allsymbols) allsymbols = g_module_open(NULL, 0);\n"
3884 "\tif (allsymbols) {\n"
3885 "\t\tgchar * func_name = g_strdup_printf(\"%s_%%s\", handler_name);\n"
3886 "\t\tGCallback func;\n"
3888 "\t\tif (!g_module_symbol(allsymbols, func_name, (gpointer)&func)){\n"
3889 "\t\t\tif (!g_module_symbol(allsymbols, handler_name, (gpointer)&func)) {\n"
3890 "\t\t\t\tg_warning(\"could not find signal handler '%%s'.\", func_name);\n"
3891 "\t\t\t\tg_free(func_name);\n"
3896 "\t\t\tg_signal_connect_data(object, signal_name, func, user_data, NULL, G_CONNECT_AFTER | G_CONNECT_SWAPPED);\n"
3898 "\t\t\tg_signal_connect_data(object, signal_name, func, user_data, NULL, G_CONNECT_SWAPPED);\n"
3899 "\t\tg_free(func_name);\n"
3906 for (li = nodes; li != NULL; li = li->next) {
3907 Node *node = li->data;
3908 if (node->type == CCODE_NODE) {
3909 CCode *cc = (CCode *)node;
3910 if (cc->cctype == AD_CCODE)
3911 print_ccode_block (cc);
3915 if (need_constructor)
3916 add_constructor (c);
3926 if(set_properties > 0) {
3927 add_getset_arg(c, TRUE);
3930 if(get_properties > 0) {
3931 add_getset_arg(c, FALSE);
3934 for(li = c->nodes; li != NULL; li = li->next) {
3936 if(n->type == METHOD_NODE)
3937 put_method((Method *)n);
3940 add_bad_hack_to_avoid_unused_warnings(c);
3944 print_useful_macros(void)
3946 int major = 0, minor = 0, pl = 0;
3949 sscanf (VERSION, "%d.%d.%d", &major, &minor, &pl);
3950 out_printf (out, "#define GOB_VERSION_MAJOR %d\n", major);
3951 out_printf (out, "#define GOB_VERSION_MINOR %d\n", minor);
3952 out_printf (out, "#define GOB_VERSION_PATCHLEVEL %d\n\n", pl);
3954 /* Useful priv macro thingie */
3955 /* FIXME: this should be done the same way that priv is, as a var,
3957 out_printf (out, "#define selfp (self->_priv)\n\n");
3961 print_more_useful_macros (void)
3964 out_printf (out, "#define ___GOB_LIKELY(expr) (expr)\n");
3965 out_printf (out, "#define ___GOB_UNLIKELY(expr) (expr)\n");
3967 out_printf (out, "#ifdef G_LIKELY\n");
3968 out_printf (out, "#define ___GOB_LIKELY(expr) G_LIKELY(expr)\n");
3969 out_printf (out, "#define ___GOB_UNLIKELY(expr) G_UNLIKELY(expr)\n");
3970 out_printf (out, "#else /* ! G_LIKELY */\n");
3971 out_printf (out, "#define ___GOB_LIKELY(expr) (expr)\n");
3972 out_printf (out, "#define ___GOB_UNLIKELY(expr) (expr)\n");
3973 out_printf (out, "#endif /* G_LIKELY */\n");
3978 print_file_comments(void)
3980 out_printf(outh, "/* Generated by GOB (v%s)"
3981 " (do not edit directly) */\n\n", VERSION);
3983 out_printf(outph, "/* Generated by GOB (v%s)"
3984 " (do not edit directly) */\n\n", VERSION);
3985 out_printf(out, "/* Generated by GOB (v%s)"
3986 " (do not edit directly) */\n\n", VERSION);
3988 out_printf(out, "/* End world hunger, donate to the World Food Programme, http://www.wfp.org */\n\n");
3992 print_includes(void)
3994 gboolean found_header;
3997 /* We may need string.h for memset */
3998 if ( ! g_list_find_custom(include_files, "string.h", (GCompareFunc)strcmp)) {
3999 out_printf(out, "#include <string.h> /* memset() */\n\n");
4002 p = g_strconcat(filebase, ".h", NULL);
4003 found_header = TRUE;
4004 if( ! g_list_find_custom(include_files, p, (GCompareFunc)strcmp)) {
4005 out_printf(out, "#include \"%s.h\"\n\n", filebase);
4006 found_header = FALSE;
4010 /* if we are creating a private header see if it was included */
4012 char sep[2] = {0,0};
4015 p = g_strconcat(filebase, sep, "private.h", NULL);
4016 if( ! g_list_find_custom(include_files, p,
4017 (GCompareFunc)strcmp)) {
4018 out_printf(out, "#include \"%s%sprivate.h\"\n\n",
4022 error_printf(GOB_WARN, 0,
4023 "Implicit private header include "
4025 "\tsource file, while public "
4026 "header is at a custom location, "
4028 "\texplicitly include "
4029 "the private header below the "
4037 print_header_prefixes(void)
4041 p = replace_sep(((Class *)class)->otype, '_');
4043 out_printf(outh, "#ifndef __%s_H__\n#define __%s_H__\n\n", p, p);
4045 out_printf(outph, "#ifndef __%s_PRIVATE_H__\n"
4046 "#define __%s_PRIVATE_H__\n\n"
4047 "#include \"%s.h\"\n\n", p, p, filebase);
4050 if( ! no_extern_c) {
4051 out_printf(outh, "#ifdef __cplusplus\n"
4053 "#endif /* __cplusplus */\n\n");
4055 out_printf(outph, "#ifdef __cplusplus\n"
4057 "#endif /* __cplusplus */\n\n");
4062 print_header_postfixes(void)
4065 out_printf(outh, "\n#ifdef __cplusplus\n"
4067 "#endif /* __cplusplus */\n");
4068 out_printf(outh, "\n#endif\n");
4071 out_printf(outph, "\n#ifdef __cplusplus\n"
4073 "#endif /* __cplusplus */\n");
4074 out_printf(outph, "\n#endif\n");
4083 /* print the AT_CCODE and CT_CCODE blocks */
4084 for(li = nodes; li != NULL; li = li->next) {
4085 Node *node = li->data;
4086 if(node->type == CCODE_NODE) {
4087 CCode *cc = (CCode *)node;
4088 if (cc->cctype == AT_CCODE ||
4089 cc->cctype == CT_CCODE)
4090 print_ccode_block((CCode *)node);
4096 print_header_top(void)
4100 /* mandatory includes */
4101 out_printf (outh, "#include <glib.h>\n");
4102 out_printf (outh, "#include <glib-object.h>\n");
4104 /* print the HT_CCODE blocks */
4105 for (li = nodes; li != NULL; li = li->next) {
4106 Node *node = li->data;
4107 if (node->type == CCODE_NODE) {
4108 CCode *cc = (CCode *)node;
4109 if (cc->cctype == HT_CCODE)
4110 print_ccode_block ((CCode *)node);
4116 print_enum (EnumDef *enode)
4123 funcprefix = replace_sep (enode->etype, '_');
4124 gob_strdown (funcprefix);
4125 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
4127 type = remove_sep (enode->etype);
4129 out_printf (outh, "\ntypedef enum {\n");
4131 for (li = enode->values; li != NULL; li = li->next) {
4132 EnumValue *value = li->data;
4134 char *sname = gob_strdown (g_strdup (value->name));
4136 while ((p = strchr (sname, '_')) != NULL)
4139 out_printf (outh, "\t%s_%s", enode->prefix, value->name);
4140 if (value->value != NULL)
4141 out_printf (outh, " = %s", value->value);
4142 if (li->next != NULL)
4143 out_printf (outh, ",\n");
4145 out_printf (outh, "\n");
4147 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
4148 enode->prefix, value->name,
4149 enode->prefix, value->name,
4155 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
4157 out_printf (outh, "} %s;\n", type);
4159 str = make_pre_macro (enode->etype, "TYPE");
4160 out_printf (outh, "#define %s ", str);
4163 out_printf (outh, "%s_get_type()\n", funcprefix);
4164 out_printf (outh, "GType %s_get_type (void) G_GNUC_CONST;\n\n", funcprefix);
4167 "GType\n%s_get_type (void)\n"
4169 "\tstatic GType type = 0;\n"
4170 "\tif ___GOB_UNLIKELY(type == 0)\n"
4171 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
4174 funcprefix, type, funcprefix);
4176 g_free (funcprefix);
4181 print_flags (Flags *fnode)
4189 funcprefix = replace_sep (fnode->ftype, '_');
4190 gob_strdown (funcprefix);
4191 out_printf (out, "static const GFlagsValue _%s_values[] = {\n",
4193 type = remove_sep (fnode->ftype);
4195 out_printf (outh, "\ntypedef enum {\n");
4197 for (i = 0, li = fnode->values; li != NULL; i++, li = li->next) {
4198 const char *name = li->data;
4200 char *sname = gob_strdown (g_strdup (name));
4202 while ((p = strchr (sname, '_')) != NULL)
4205 out_printf (outh, "\t%s_%s = 1<<%d",
4206 fnode->prefix, name, i);
4207 if (li->next != NULL)
4208 out_printf (outh, ",\n");
4210 out_printf (outh, "\n");
4212 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
4213 fnode->prefix, name,
4214 fnode->prefix, name,
4220 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
4222 out_printf (outh, "} %s;\n", type);
4224 str = make_pre_macro (fnode->ftype, "TYPE");
4225 out_printf (outh, "#define %s ", str);
4228 out_printf (outh, "%s_get_type()\n", funcprefix);
4229 out_printf (outh, "GType %s_get_type (void) G_GNUC_CONST;\n\n", funcprefix);
4232 "GType\n%s_get_type (void)\n"
4234 "\tstatic GType type = 0;\n"
4235 "\tif ___GOB_UNLIKELY(type == 0)\n"
4236 "\t\ttype = g_flags_register_static (\"%s\", _%s_values);\n"
4239 funcprefix, type, funcprefix);
4241 g_free (funcprefix);
4246 print_error (Error *enode)
4253 funcprefix = replace_sep (enode->etype, '_');
4254 gob_strdown (funcprefix);
4255 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
4257 type = remove_sep (enode->etype);
4259 out_printf (outh, "\ntypedef enum {\n");
4261 for (li = enode->values; li != NULL; li = li->next) {
4262 const char *name = li->data;
4264 char *sname = gob_strdown (g_strdup (name));
4266 while ((p = strchr (sname, '_')) != NULL)
4269 out_printf (outh, "\t%s_%s", enode->prefix, name);
4270 if (li->next != NULL)
4271 out_printf (outh, ",\n");
4273 out_printf (outh, "\n");
4275 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
4276 enode->prefix, name,
4277 enode->prefix, name,
4283 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
4285 out_printf (outh, "} %s;\n", type);
4287 str = make_pre_macro (enode->etype, "TYPE");
4288 out_printf (outh, "#define %s ", str);
4291 out_printf (outh, "%s_get_type ()\n", funcprefix);
4292 out_printf (outh, "GType %s_get_type (void) G_GNUC_CONST;\n\n", funcprefix);
4295 "GType\n%s_get_type (void)\n"
4297 "\tstatic GType type = 0;\n"
4298 "\tif ___GOB_UNLIKELY(type == 0)\n"
4299 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
4302 funcprefix, type, funcprefix);
4304 out_printf (outh, "#define %s %s_quark ()\n", enode->prefix, funcprefix);
4305 out_printf (outh, "GQuark %s_quark (void);\n\n", funcprefix);
4307 str = replace_sep (enode->etype, '-');
4311 "GQuark\n%s_quark (void)\n"
4313 "\tstatic GQuark q = 0;\n"
4315 "\t\tq = g_quark_from_static_string (\"%s\");\n"
4322 g_free (funcprefix);
4327 generate_outfiles(void)
4331 print_file_comments();
4337 print_header_prefixes();
4339 print_useful_macros();
4343 print_more_useful_macros ();
4345 for (li = nodes; li != NULL; li = li->next) {
4346 Node *node = li->data;
4347 if (node->type == CCODE_NODE) {
4348 CCode *cc = (CCode *)node;
4349 if (cc->cctype != HT_CCODE &&
4350 cc->cctype != AT_CCODE &&
4351 cc->cctype != AD_CCODE)
4352 print_ccode_block ((CCode *)node);
4353 } else if (node->type == CLASS_NODE) {
4354 print_class_block ((Class *)node);
4355 } else if (node->type == ENUMDEF_NODE) {
4356 print_enum ((EnumDef *)node);
4357 } else if (node->type == FLAGS_NODE) {
4358 print_flags ((Flags *)node);
4359 } else if (node->type == ERROR_NODE) {
4360 print_error ((Error *)node);
4362 g_assert_not_reached();
4366 print_header_postfixes();
4372 fprintf(stderr, "Gob version %s\n\n", VERSION);
4373 fprintf(stderr, "gob [options] file.gob\n\n");
4374 fprintf(stderr, "Options:\n"
4375 "\t--help,-h,-? Display this help\n"
4376 "\t--version Display version\n"
4377 "\t--exit-on-warn,-w Exit with an error on warnings\n"
4378 "\t--no-exit-on-warn Don't exit on warnings [default]\n"
4379 "\t--for-cpp Create C++ files\n"
4380 "\t--no-extern-c Never print extern \"C\" into the "
4382 "\t--no-gnu Never use GNU extentions\n"
4383 "\t--no-touch Don't touch output files unless they "
4385 "\t changed (implies --no-touch-headers)\n"
4386 "\t--no-touch-headers Don't touch headers unless they "
4388 "\t--always-private-header Always create a private header "
4390 "\t even if it would be empty\n"
4391 "\t--ondemand-private-header Create private header only when "
4394 "\t--no-private-header Don't create a private header, "
4396 "\t structure and protected "
4397 "prototypes inside c file\n"
4398 "\t--always-private-struct Always create a private pointer "
4400 "\t the object structure\n"
4401 "\t--m4 Preprocess source with m4. "
4402 "Following args will\n"
4403 "\t be passed to m4\n"
4404 "\t--m4-dir Print directory that will be "
4407 "\t--no-write,-n Don't write output files, just "
4409 "\t--no-lines Don't print '#line' to output\n"
4410 "\t--no-self-alias Don't create self type and macro "
4412 "\t--no-kill-underscores Ignored for compatibility\n"
4413 "\t-o,--output-dir The directory where output "
4414 "should be placed\n"
4415 "\t--file-sep[=c] replace default \'-\' file "
4416 "name separator\n\n"
4417 "\t--gtk3 Use gtk+3\n"
4419 fprintf(stderr, "End world hunger, donate to the World Food Programme, http://www.wfp.org\n");
4423 parse_options(int argc, char *argv[])
4426 int got_file = FALSE;
4427 int no_opts = FALSE;
4428 int m4_opts = FALSE; /* if we are just passing on args to m4 */
4432 for(i = 1 ; i < argc; i++) {
4434 char *new_commandline;
4435 g_assert(m4_commandline!=NULL);
4437 /* check whether this one looks like the filename */
4438 if((!strcmp(argv[i],"-") || argv[i][0] != '-')
4440 const gchar *m4_flags=use_m4_clean?"":M4_FLAGS;
4444 /* insert flags before the filename */
4445 new_commandline=g_strconcat(m4_commandline,
4453 /* just an ordinary option */
4455 new_commandline=g_strconcat(m4_commandline,
4460 /* free old commandline */
4461 g_free(m4_commandline);
4462 m4_commandline=new_commandline;
4464 } else if(no_opts ||
4465 argv[i][0] != '-') {
4468 fprintf(stderr, "Specify only one file!\n");
4474 } else if(strcmp(argv[i], "--help")==0) {
4477 } else if(strcmp(argv[i], "--version")==0) {
4478 fprintf(stderr, "Gob version %s\n", VERSION);
4480 } else if(strcmp(argv[i], "--exit-on-warn")==0) {
4481 exit_on_warn = TRUE;
4482 } else if(strcmp(argv[i], "--no-exit-on-warn")==0) {
4483 exit_on_warn = FALSE;
4484 } else if(strcmp(argv[i], "--for-cpp")==0) {
4486 } else if(strcmp(argv[i], "--no-touch")==0) {
4488 no_touch_headers = TRUE;
4489 } else if(strcmp(argv[i], "--no-touch-headers")==0) {
4490 no_touch_headers = TRUE;
4491 } else if(strcmp(argv[i], "--ondemand-private-header")==0) {
4492 private_header = PRIVATE_HEADER_ONDEMAND;
4493 } else if(strcmp(argv[i], "--always-private-header")==0) {
4494 private_header = PRIVATE_HEADER_ALWAYS;
4495 } else if(strcmp(argv[i], "--no-private-header")==0) {
4496 private_header = PRIVATE_HEADER_NEVER;
4497 } else if(strcmp(argv[i], "--no-gnu")==0) {
4499 } else if(strcmp(argv[i], "--no-extern-c")==0) {
4501 } else if(strcmp(argv[i], "--no-write")==0) {
4503 } else if(strcmp(argv[i], "--no-lines")==0) {
4505 } else if(strcmp(argv[i], "--no-self-alias")==0) {
4506 no_self_alias = TRUE;
4507 } else if(strcmp(argv[i], "--no-kill-underscores")==0) {
4509 } else if(strcmp(argv[i], "--always-private-struct")==0) {
4510 always_private_struct = TRUE;
4511 } else if(strcmp(argv[i], "--m4-dir")==0) {
4512 printf("%s\n",M4_INCLUDE_DIR);
4514 } else if(strcmp(argv[i], "--m4")==0) {
4518 m4_commandline=g_strdup(M4_COMMANDLINE);
4519 } else if(strcmp(argv[i], "--m4-clean")==0) {
4523 m4_commandline=g_strdup(M4_COMMANDLINE);
4524 } else if (strcmp (argv[i], "-o") == 0 ||
4525 strcmp (argv[i], "--output-dir") == 0) {
4527 output_dir = g_strdup (argv[i+1]);
4532 } else if (strncmp (argv[i], "-o=", strlen ("-o=")) == 0 ||
4535 strlen ("--output-dir=")) == 0) {
4536 char *p = strchr (argv[i], '=');
4537 g_assert (p != NULL);
4538 output_dir = g_strdup (p+1);
4539 } else if (strncmp (argv[i], "--file-sep=",
4540 strlen ("--file-sep=")) == 0) {
4541 char *p = strchr (argv[i], '=');
4542 g_assert (p != NULL);
4544 } else if (strncmp (argv[i], "--file-sep",
4545 strlen ("--file-sep")) == 0) {
4547 file_sep = (argv[i+1])[0];
4552 } else if(strcmp(argv[i], "--gtk3")==0) {
4554 } else if(strcmp(argv[i], "--")==0) {
4555 /*further arguments are files*/
4557 } else if(strncmp(argv[i], "--", 2)==0) {
4558 /*unknown long option*/
4559 fprintf(stderr, "Unknown option '%s'!\n", argv[i]);
4563 /*by now we know we have a string starting with
4564 - which is a short option string*/
4566 for(p = argv[i] + 1; *p; p++) {
4580 "Unknown option '%c'!\n", *p);
4589 /* if we are using m4, and got no filename, append m4 flags now */
4590 if(!got_file && use_m4 && !use_m4_clean) {
4591 char *new_commandline;
4592 new_commandline=g_strconcat(m4_commandline,
4596 g_free(m4_commandline);
4597 m4_commandline=new_commandline;
4603 compare_and_move (const char *old_filename)
4605 char *new_filename = g_strconcat (old_filename, "#gob#", NULL);
4607 gboolean equal = FALSE;
4609 old_f = fopen (old_filename, "r");
4612 gboolean error = FALSE;
4614 new_f = fopen (new_filename, "r");
4623 new_n = fread (new_buf, 1, sizeof (new_buf), new_f);
4624 if (ferror (new_f)) {
4626 error_printf (GOB_ERROR, 0,
4627 "Can't read %s: %s",
4629 g_strerror (errno));
4633 old_n = fread (old_buf, 1, sizeof (old_buf), old_f);
4635 || feof (new_f) != feof (old_f)
4637 || memcmp (new_buf, old_buf, new_n) != 0)
4646 error_printf (GOB_ERROR, 0, "Can't open %s: %s",
4647 new_filename, g_strerror (errno));
4655 if (! equal && unlink (old_filename) != 0) {
4656 error_printf (GOB_ERROR, 0, "Can't remove %s: %s",
4657 old_filename, g_strerror (errno));
4663 if (unlink (new_filename) != 0)
4664 error_printf (GOB_ERROR, 0, "Can't remove %s: %s",
4665 new_filename, g_strerror (errno));
4667 if (rename (new_filename, old_filename) != 0)
4668 error_printf (GOB_ERROR, 0, "Can't rename %s to %s: %s",
4669 new_filename, old_filename,
4670 g_strerror (errno));
4674 g_free (new_filename);
4678 main(int argc, char *argv[])
4680 parse_options(argc, argv);
4683 yyin = popen(m4_commandline, "r");
4685 fprintf(stderr, "Error: can't open pipe from '%s'\n",
4689 } else if(filename) {
4690 yyin = fopen(filename, "r");
4692 fprintf(stderr, "Error: can't open file '%s'\n",
4701 /* This is where parsing is done */
4704 error_print (GOB_ERROR, 0, "Parsing errors, quitting");
4706 /* close input file */
4707 if(use_m4) pclose(yyin);
4712 error_print (GOB_ERROR, 0, "no class defined");
4715 exit_on_error = FALSE;
4717 signals = count_signals ((Class *)class);
4718 set_properties = count_set_properties ((Class *)class) +
4719 count_set_arguments ((Class *)class);
4720 get_properties = count_get_properties ((Class *)class) +
4721 count_get_arguments ((Class *)class);
4722 overrides = count_overrides ((Class *)class);
4723 privates = count_privates ((Class *)class);
4724 protecteds = count_protecteds ((Class *)class);
4725 unreftors = count_unreftors ((Class *)class);
4726 destructors = count_destructors ((Class *)class);
4727 initializers = count_initializers ((Class *)class);
4728 glade_widgets = count_glade_widgets ((Class *)class);
4729 overrode_get_type = find_get_type ((Class *)class);
4732 make_inits ((Class *)class);
4734 find_constructor ((Class *)class);
4735 if (user_constructor != NULL)
4736 need_constructor = TRUE;
4738 find_dispose ((Class *)class);
4739 if (unreftors > 0 ||
4740 dispose_handler != NULL ||
4741 user_dispose_method != NULL)
4742 need_dispose = TRUE;
4744 find_finalize ((Class *)class);
4745 if (destructors > 0 ||
4747 user_finalize_method != NULL) {
4748 need_finalize = TRUE;
4751 check_bad_symbols ((Class *)class);
4752 check_duplicate_symbols ((Class *)class);
4753 check_duplicate_overrides ((Class *)class);
4754 check_duplicate_signals_args ((Class *)class);
4755 check_public_new ((Class *)class);
4756 check_vararg ((Class *)class);
4757 check_firstarg ((Class *)class);
4758 check_nonvoidempty ((Class *)class);
4759 check_signal_args ((Class *)class);
4760 check_property_types ((Class *)class);
4761 check_argument_types ((Class *)class);
4762 check_func_arg_checks ((Class *)class);
4763 check_func_attrs ((Class *)class);
4764 check_for_class_destructors ((Class *)class);
4766 exit_on_error = TRUE;
4771 any_special = setup_special_array ((Class *)class, special_array);
4775 generate_outfiles ();
4786 compare_and_move (outfilebase);
4788 compare_and_move (outfilephbase);
4790 if (no_touch_headers)
4791 compare_and_move (outfilehbase);