2 * Copyright (C) 1999,2000 the Free Software Foundation.
3 * Copyright (C) 2000 Eazel, Inc.
4 * Copyright (C) 2001-2011 George (Jiri) Lebl
5 * Copyright © 2019-2020 Nick Bowler
7 * Author: George (Jiri) Lebl
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
35 #include "treefuncs.h"
43 char *filename = NULL;
53 extern GList *include_files;
55 extern GHashTable *gtk_doc_hash;
59 static char *outfilebase;
60 static char *outfilehbase;
61 static char *outfilephbase;
62 static char *funcbase;
63 static char *pfuncbase;
64 static char *macrobase;
66 static char *pmacrois;
67 static char *macrotype;
68 static char *pmacrotype;
69 static char *typebase;
70 static char *ptypebase;
72 char *output_dir = NULL;
76 static int signals = 0; /* number of signals */
77 static int set_properties = 0; /* number of named (set) properties */
78 static int get_properties = 0; /* number of named (get) properties */
79 static int overrides = 0; /* number of override methods */
80 static int privates = 0; /* number of private data members */
81 static int protecteds = 0; /* number of protected methods */
82 static int unreftors = 0; /* number of variable unreffing destructors */
83 static int destructors = 0; /* number of variable non-unreffing destructors */
84 static int initializers = 0; /* number of variable initializers */
85 static int glade_widgets = 0; /* number of glade widgets */
86 static gboolean overrode_get_type = FALSE; /* provided your won _get_type */
88 static gboolean made_aliases = FALSE; /* if we made any shorthand aliases
89 and need the REALLY UGLY HACK to
92 /* the special variable types we need to define */
93 static gboolean special_array[SPECIAL_LAST] = {0};
94 static gboolean any_special = FALSE;
96 static gboolean need_constructor = FALSE;
97 static Method * user_constructor = NULL;
99 static gboolean need_dispose = FALSE;
100 static Method * dispose_handler = NULL;
101 static Method * user_dispose_method = NULL;
103 static gboolean need_finalize = FALSE;
104 static Method * finalize_handler = NULL;
105 static Method * user_finalize_method = NULL;
111 gboolean no_touch = FALSE;
112 gboolean no_touch_headers = FALSE;
113 gboolean for_cpp = FALSE;
114 gboolean no_gnu = FALSE;
115 gboolean exit_on_warn = FALSE;
116 gboolean exit_on_error = TRUE;
117 gboolean got_error = FALSE;
118 gint private_header = PRIVATE_HEADER_ONDEMAND;
119 gboolean no_extern_c = FALSE;
120 gboolean no_write = FALSE;
121 gboolean no_lines = FALSE;
122 gboolean no_self_alias = FALSE;
123 gboolean always_private_struct = FALSE;
124 gboolean gtk3_ok = FALSE;
130 gboolean use_m4 = FALSE; /* preprocess sources with m4 */
131 gboolean use_m4_clean = FALSE; /* preprocess sources with m4, no m4 flags */
132 char *m4_commandline = NULL;
133 #define M4_INCLUDE_DIR PKGDATADIR "/m4"
134 #define M4_BASE_FILENAME "gobm4.m4"
135 #define M4_FLAGS "-P -s -I" M4_INCLUDE_DIR " -DGOBM4_GOB_VERSION=" VERSION " " M4_BASE_FILENAME
136 #define M4_COMMANDLINE "m4"
138 int method_unique_id = 1;
143 filebase = replace_sep (((Class *)class)->otype, file_sep);
144 gob_strdown (filebase);
146 if (output_dir != NULL &&
147 output_dir[0] != '\0') {
148 fullfilebase = g_build_filename (output_dir, filebase, NULL);
150 fullfilebase = g_strdup (filebase);
153 funcbase = replace_sep (((Class *)class)->otype, '_');
154 gob_strdown (funcbase);
156 pfuncbase = replace_sep (((Class *)class)->ptype, '_');
157 gob_strdown (pfuncbase);
159 macrobase = replace_sep (((Class *)class)->otype, '_');
160 gob_strup (macrobase);
162 macrois = make_pre_macro (((Class *)class)->otype, "IS");
163 pmacrois = make_pre_macro (((Class *)class)->ptype, "IS");
165 macrotype = make_pre_macro (((Class *)class)->otype, "TYPE");
166 pmacrotype = make_pre_macro (((Class *)class)->ptype, "TYPE");
168 typebase = remove_sep (((Class *)class)->otype);
170 ptypebase = remove_sep (((Class *)class)->ptype);
174 get_gtk_doc (const char *id)
181 val = g_hash_table_lookup(gtk_doc_hash, id);
183 return g_strdup_printf("/**\n * %s_%s:\n%s **/\n",
185 val = g_hash_table_lookup(gtk_doc_hash, id);
187 return g_strdup_printf("/**\n * %s_%s:\n%s **/\n",
193 print_type(FILE *fp, const Type *t, gboolean postfix_to_stars)
197 s = get_type(t, postfix_to_stars);
198 out_printf(fp, "%s", s);
204 print_method (FILE *fp,
205 const char *typeprefix,
206 const char *nameprefix,
207 const char *subnameprefix,
208 const char *namepostfix,
209 const char *afterargs,
212 gboolean print_funcattrs,
213 gboolean one_arg_per_line,
214 gboolean no_funcbase,
215 gboolean kill_underscore,
216 gboolean first_unused,
222 out_printf(fp, "%s", typeprefix);
223 print_type(fp, m->mtype, TRUE);
228 out_printf(fp, "%s%s%s%s(",
229 nameprefix, subnameprefix, id, namepostfix);
231 out_printf(fp, "%s%s_%s%s%s(",
232 nameprefix, funcbase, subnameprefix, id,
236 for(li=m->args; li; li=g_list_next(li)) {
237 FuncArg *arg = li->data;
238 const char *unused = "";
241 ! for_cpp && /* g++ has a cow with this */
244 unused = " G_GNUC_UNUSED";
247 print_type(fp, arg->atype, FALSE);
249 out_printf (fp, "___fake___");
251 out_printf(fp, "%s%s%s,%s", arg->name,
252 arg->atype->postfix ?
253 arg->atype->postfix : "",
255 one_arg_per_line ? "\n\t\t\t\t\t" : " ");
257 out_printf(fp, "%s%s%s", arg->name,
258 arg->atype->postfix ?
259 arg->atype->postfix : "",
263 out_printf(fp, ",%s...",
264 one_arg_per_line ? "\n\t\t\t\t\t" : " ");
266 out_printf(fp, "void");
268 /* Slightly icky: sometimes we are called st m->funcattrs
269 hasn't been set, but if so it should be NULL since its been
271 if(print_funcattrs && m->funcattrs != NULL
272 && strlen(m->funcattrs) > 0) {
273 /* To keep the output neat, we trim off the trailing '\n'
274 from the end of funcattrs for a moment. */
275 size_t funcattrs_len = strlen(m->funcattrs);
276 gboolean funcattrs_chomped = FALSE;
277 if((m->funcattrs)[funcattrs_len - 1] == '\n') {
278 m->funcattrs[funcattrs_len - 1] = '\0';
279 funcattrs_chomped = TRUE;
281 out_printf(fp, "%s)\n%s%s", afterargs, m->funcattrs, postfix);
282 /* Put it back like it was (though it shouldn't matter). */
283 if (funcattrs_chomped) {
284 (m->funcattrs)[funcattrs_len - 1] = '\n';
288 out_printf(fp, "%s)%s", afterargs, postfix);
293 any_method_to_alias(Class *c)
297 for(li=c->nodes;li;li=g_list_next(li)) {
298 Node *node = li->data;
299 if(node->type == METHOD_NODE) {
300 Method *m = (Method *)node;
302 if(m->method == INIT_METHOD ||
303 m->method == CLASS_INIT_METHOD ||
304 m->method == CONSTRUCTOR_METHOD ||
305 m->method == DISPOSE_METHOD ||
306 m->method == FINALIZE_METHOD ||
307 m->method == OVERRIDE_METHOD)
318 make_method_aliases (Class *c)
322 for(li = c->nodes; li != NULL; li = li->next) {
323 Node *node = li->data;
324 if(node->type == METHOD_NODE) {
325 Method *m = (Method *)node;
327 if(m->method == INIT_METHOD ||
328 m->method == CLASS_INIT_METHOD ||
329 m->method == CONSTRUCTOR_METHOD ||
330 m->method == DISPOSE_METHOD ||
331 m->method == FINALIZE_METHOD ||
332 m->method == OVERRIDE_METHOD)
335 out_printf (out, "#define self_%s %s_%s\n",
344 add_bad_hack_to_avoid_unused_warnings(const Class *c)
348 /* if we haven't had any methods, just return */
353 out_printf(out, "\n\n#if (!defined __GNUC__) || (defined __GNUC__ && defined __STRICT_ANSI__)\n");
355 "/*REALLY BAD HACK\n"
356 " This is to avoid unused warnings if you don't call\n"
357 " some method. I need to find a better way to do\n"
358 " this, not needed in GCC since we use some gcc\n"
359 " extentions to make saner, faster code */\n"
361 "___%s_really_bad_hack_to_avoid_warnings(void)\n"
363 out_printf(out, "\t((void (*)(void))GET_NEW_VARG)();\n");
364 for(li=c->nodes;li;li=g_list_next(li)) {
365 Node *node = li->data;
366 if(node->type == METHOD_NODE) {
367 Method *m = (Method *)node;
369 if(m->method == INIT_METHOD ||
370 m->method == CLASS_INIT_METHOD ||
371 m->method == CONSTRUCTOR_METHOD ||
372 m->method == DISPOSE_METHOD ||
373 m->method == FINALIZE_METHOD ||
374 m->method == OVERRIDE_METHOD)
377 /* in C++ mode we don't alias new */
378 if(for_cpp && strcmp(m->id, "new")==0)
381 out_printf(out, "\t((void (*)(void))self_%s)();\n", m->id);
384 out_printf(out, "\t___%s_really_bad_hack_to_avoid_warnings();\n",
387 out_printf(out, "}\n#endif /* !__GNUC__ || (__GNUC__ && __STRICT_ANSI__) */\n\n");
389 out_printf(out, "}\n\n");
393 put_variable(const Variable *v, FILE *fp)
395 out_printf(fp, "\t");
396 print_type(fp, v->vtype, FALSE);
397 out_printf(fp, "%s%s;", v->id,
399 v->vtype->postfix:"");
400 if(v->scope == PROTECTED_SCOPE)
401 out_printf(fp, " /* protected */");
402 out_printf(fp, "\n");
406 put_vs_method(const Method *m)
408 if(m->method != SIGNAL_LAST_METHOD &&
409 m->method != SIGNAL_FIRST_METHOD &&
410 m->method != VIRTUAL_METHOD)
413 /* if a signal mark it as such */
414 if(m->method != VIRTUAL_METHOD)
415 print_method(outh, "\t/*signal*/", "(* ", "", ") ", "", ";\n",
416 m, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE);
418 print_method(outh, "\t", "(* ", "", ") ", "", ";\n",
419 m, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE);
424 put_pub_method(const Method *m)
426 if(m->scope != PUBLIC_SCOPE)
429 out_addline_infile(outh, m->line_no);
430 print_method(outh, "", "\t", "", "\t", "", ";\n", m,
431 TRUE, TRUE, FALSE, TRUE, FALSE, FALSE);
432 out_addline_outfile(outh);
436 put_signal_macro (const Method *m, gboolean gnu)
438 if(m->method != SIGNAL_LAST_METHOD &&
439 m->method != SIGNAL_FIRST_METHOD)
444 out_printf (outh, "#define %s_connect__%s(object,func,data)\t"
445 "g_signal_connect(%s(object),\"%s\","
446 "(GCallback)(func),(data))\n",
447 funcbase, m->id, macrobase, m->id);
450 out_printf (outh, "#define %s_connect_after__%s(object,func,data)\t"
451 "g_signal_connect_after(%s(object),\"%s\","
452 "(GCallback)(func),(data))\n",
453 funcbase, m->id, macrobase, m->id);
456 out_printf (outh, "#define %s_connect_data__%s"
457 "(object,func,data,destroy_data,flags)\t"
458 "g_signal_connect_data(%s(object),\"%s\","
459 "(GCallback)(func),(data),(destroy_data),(GConnectFlags)(flags))\n",
460 funcbase, m->id, macrobase, m->id);
463 out_printf (outh, "#define %s_connect__%s(object,func,data)\t"
465 "%s(__extension__ ({%s *___object = (object); ___object; })),"
467 "(GCallback) __extension__ ({",
468 funcbase, m->id, macrobase, typebase, m->id);
469 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
470 " = (func); ", m, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE);
471 out_printf (outh, "___%s; }), (data))\n", m->id);
474 out_printf (outh, "#define %s_connect_after__%s(object,func,data)\t"
475 "g_signal_connect_after("
476 "%s(__extension__ ({%s *___object = (object); ___object; })),"
478 "(GCallback) __extension__ ({",
479 funcbase, m->id, macrobase, typebase, m->id);
480 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
481 " = (func); ", m, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE);
482 out_printf (outh, "___%s; }), (data))\n", m->id);
485 out_printf (outh, "#define %s_connect_data__%s"
486 "(object,func,data,destroy_data,flags)\t"
487 "g_signal_connect_data("
488 "%s(__extension__ ({%s *___object = (object); ___object; })),"
490 "(GCallback) __extension__ ({",
491 funcbase, m->id, macrobase, typebase, m->id);
492 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
493 " = (func); ", m, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE);
494 out_printf (outh, "___%s; }), (data), (destroy_data), (GConnectFlags)(flags))\n", m->id);
499 put_signal_macros (const Class *c, gboolean gnu)
506 for (li = c->nodes; li != NULL; li = li->next) {
507 const Node *n = li->data;
508 if (n->type == METHOD_NODE)
509 put_signal_macro ((Method *)n, gnu);
514 put_local_signal_macro (const Method *m)
516 if(m->method != SIGNAL_LAST_METHOD &&
517 m->method != SIGNAL_FIRST_METHOD)
521 out_printf (out, "#define self_connect__%s(object,func,data)\t"
522 "%s_connect__%s((object),(func),(data))\n",
523 m->id, funcbase, m->id);
526 out_printf (out, "#define self_connect_after__%s(object,func,data)\t"
527 "%s_connect_after__%s((object),(func),(data))\n",
528 m->id, funcbase, m->id);
531 out_printf (out, "#define self_connect_data__%s(object,func,data,destroy_data,flags)\t"
532 "%s_connect_data__%s((object),(func),(data),(destroy_data),(flags))\n",
533 m->id, funcbase, m->id);
537 put_local_signal_macros (const Class *c)
544 for (li = c->nodes; li != NULL; li = li->next) {
545 const Node *n = li->data;
546 if (n->type == METHOD_NODE)
547 put_local_signal_macro ((Method *)n);
553 put_prot_method(const Method *m)
557 if(m->scope != PROTECTED_SCOPE)
560 f = outph ? outph : out;
562 out_addline_infile(f, m->line_no);
563 print_method(f, "", "\t", "", "\t", "", ";\n",
564 m, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE);
565 out_addline_outfile(f);
569 put_priv_method_prot(const Method *m)
571 if(m->method == SIGNAL_LAST_METHOD ||
572 m->method == SIGNAL_FIRST_METHOD ||
573 m->method == VIRTUAL_METHOD) {
576 "static ", "___real_", "", " ", "", ";\n",
577 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
579 /* no else, here, it might still have a private prototype, it's not
582 if((m->method == OVERRIDE_METHOD &&
585 char *s = g_strdup_printf("___%x_", (guint)m->unique_id);
587 out_addline_infile(out, m->line_no);
588 print_method(out, "static ", s, "", " ", "",
589 no_gnu?";\n":" G_GNUC_UNUSED;\n",
590 m, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE);
592 out_addline_outfile(out);
594 } else if(m->scope == PRIVATE_SCOPE ||
595 m->method == INIT_METHOD ||
596 m->method == CLASS_INIT_METHOD ||
597 m->method == CONSTRUCTOR_METHOD ||
598 m->method == DISPOSE_METHOD ||
599 m->method == FINALIZE_METHOD) {
601 out_addline_infile(out, m->line_no);
602 print_method(out, "static ", "", "", " ", "",
603 no_gnu?";\n":" G_GNUC_UNUSED;\n",
604 m, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE);
606 out_addline_outfile(out);
611 make_func_arg (const char *typename, gboolean is_class, const char *name)
618 tn = g_strconcat (typename, ":Class", NULL);
620 tn = g_strdup (typename);
622 type = node_new (TYPE_NODE,
626 node = node_new (FUNCARG_NODE,
627 "atype:steal", (Type *)type,
630 return g_list_prepend (NULL, node);
634 make_inits(Class *cl)
636 int got_class_init = FALSE;
637 int got_init = FALSE;
640 for(li=cl->nodes;li;li=g_list_next(li)) {
642 if(n->type == METHOD_NODE) {
643 Method *m = (Method *)n;
644 if(m->method == INIT_METHOD) {
646 error_print(GOB_ERROR, m->line_no, "init defined more then once");
648 } else if(m->method == CLASS_INIT_METHOD) {
650 error_print(GOB_ERROR, m->line_no, "class_init defined more then once");
651 got_class_init = TRUE;
655 if(!got_class_init) {
656 Type *type = (Type *)node_new (TYPE_NODE,
659 node = node_new (METHOD_NODE,
661 "method", CLASS_INIT_METHOD,
664 "args:steal", make_func_arg (cl->otype,
667 "unique_id", method_unique_id++,
669 cl->nodes = g_list_prepend(cl->nodes, node);
672 Type *type = (Type *)node_new (TYPE_NODE,
675 node = node_new (METHOD_NODE,
677 "method", INIT_METHOD,
680 "args:steal", make_func_arg (cl->otype,
681 FALSE /* is_class */,
683 "unique_id", method_unique_id++,
685 cl->nodes = g_list_prepend(cl->nodes, node);
690 find_method(const Class *cl, int method, const char *id)
694 for(li=cl->nodes;li;li=g_list_next(li)) {
696 if(n->type == METHOD_NODE) {
697 Method *m = (Method *)n;
698 if (m->method == method
699 && (id == NULL || strcmp(m->id, id)==0))
708 find_constructor(const Class *cl)
710 user_constructor = find_method(cl, CONSTRUCTOR_METHOD, NULL);
714 find_dispose(const Class *cl)
716 dispose_handler = find_method(cl, OVERRIDE_METHOD, "dispose");
717 if (dispose_handler != NULL) {
718 if(strcmp(dispose_handler->otype, "G:Object") != 0)
719 error_print(GOB_ERROR, dispose_handler->line_no,
720 "dispose method override "
721 "of class other then "
723 if(g_list_length(dispose_handler->args) != 1)
724 error_print(GOB_ERROR, dispose_handler->line_no,
725 "dispose method override "
726 "with more then one "
730 user_dispose_method = find_method(cl, DISPOSE_METHOD, NULL);
734 find_finalize(const Class *cl)
736 finalize_handler = find_method(cl, OVERRIDE_METHOD, "finalize");
737 if (finalize_handler != NULL) {
738 if(strcmp(finalize_handler->otype, "G:Object") != 0)
739 error_print(GOB_ERROR, finalize_handler->line_no,
740 "finalize method override "
741 "of class other then "
743 if(g_list_length(finalize_handler->args) != 1)
744 error_print(GOB_ERROR, finalize_handler->line_no,
745 "finalize method override "
746 "with more then one "
750 user_finalize_method = find_method(cl, FINALIZE_METHOD, NULL);
754 /* hash of method -> name of signal prototype */
755 static GHashTable *marsh = NULL;
757 /* list of methods with different signal prototypes,
758 we check this list if we can use a signal prototype of a
759 previous signal method, there are only uniques here */
760 static GList *eq_signal_methods = NULL;
762 /* compare a list of strings */
764 is_list_equal(const GList *a, const GList *b)
766 for(;a && b; a=a->next, b=b->next) {
767 if(strcmp(a->data, b->data)!=0) {
771 /* the the lists were different length */
778 find_same_type_signal(const Method *m)
781 for(li=eq_signal_methods;li;li=li->next) {
782 Method *mm = li->data;
783 if(is_list_equal(mm->gtktypes, m->gtktypes))
790 print_signal_marsal_args (const Method *m)
792 if (strcmp (m->gtktypes->next->data, "NONE") != 0) {
795 for (i = 0, li = m->gtktypes->next;
797 i++, li = li->next) {
800 if (strcmp (li->data, "UNICHAR") == 0)
801 /* hack because glib is braindamaged */
802 get_func = g_strdup ("g_value_get_uint");
803 else if (strncmp(li->data, "BOXED_", 6) == 0)
804 get_func = g_strdup ("g_value_get_boxed");
806 get_func = g_strdup_printf
807 ("g_value_get_%s", (char *)li->data);
809 gob_strdown (get_func);
810 out_printf (out, ",\n\t\t(%s) "
811 "%s (param_values + %d)",
812 get_cast (li->data, FALSE),
817 out_printf (out, ",\n\t\tdata2);\n");
822 add_signal_prots(Method *m)
828 gboolean ret_none = FALSE;
829 gboolean arglist_none = FALSE;
831 const char *unused = "";
833 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
834 unused = " G_GNUC_UNUSED";
837 if (m->method != SIGNAL_LAST_METHOD &&
838 m->method != SIGNAL_FIRST_METHOD)
842 marsh = g_hash_table_new(NULL, NULL);
844 g_assert (m->gtktypes->next != NULL);
846 ret_none = strcmp(m->gtktypes->data, "NONE") == 0;
847 arglist_none = strcmp(m->gtktypes->next->data, "NONE") == 0;
849 if (ret_none && arglist_none)
852 /* if we already did a signal prototype just use that */
853 mm = find_same_type_signal (m);
855 s = g_hash_table_lookup (marsh, mm);
856 g_hash_table_insert (marsh, m, s);
863 retcast = get_cast (m->gtktypes->data, FALSE);
865 s = g_strdup_printf("Sig%d", sig++);
867 g_hash_table_insert(marsh, m, s);
868 eq_signal_methods = g_list_prepend(eq_signal_methods, m);
870 /* we know that we'll know all the gtktypes (so get_cast can't fail) */
871 out_printf(out, "\ntypedef %s (*___%s) (%s *, ",
872 get_cast(m->gtktypes->data, FALSE), s, typebase);
874 if ( ! arglist_none) {
875 for (li = m->gtktypes->next; li != NULL; li = li->next)
876 out_printf (out, "%s, ", get_cast (li->data, FALSE));
878 out_printf (out, "gpointer);\n");
880 out_printf (out, "\nstatic void\n"
881 "___marshal_%s (GClosure *closure,\n"
882 "\tGValue *return_value%s,\n"
883 "\tguint n_param_values,\n"
884 "\tconst GValue *param_values,\n"
885 "\tgpointer invocation_hint%s,\n"
886 "\tgpointer marshal_data)\n"
893 out_printf (out, "\t%s v_return;\n", retcast);
895 out_printf (out, "\tregister ___%s callback;\n"
896 "\tregister GCClosure *cc = (GCClosure*) closure;\n"
897 "\tregister gpointer data1, data2;\n\n",
900 out_printf (out, "\tg_return_if_fail (n_param_values == %d);\n\n",
901 arglist_none ? 1 : g_list_length (m->gtktypes));
904 "\tif (G_CCLOSURE_SWAP_DATA (closure)) {\n"
905 "\t\tdata1 = closure->data;\n"
906 "\t\tdata2 = g_value_peek_pointer (param_values + 0);\n"
908 "\t\tdata1 = g_value_peek_pointer (param_values + 0);\n"
909 "\t\tdata2 = closure->data;\n"
912 out_printf (out, "\tcallback = (___%s) "
913 "(marshal_data != NULL ? marshal_data : cc->callback);"
917 out_printf (out, "\tcallback ((%s *)data1", typebase);
919 out_printf (out, "\tv_return = callback ((%s *)data1",
923 print_signal_marsal_args (m);
926 /* FIXME: This code is so fucking ugly it hurts */
927 gboolean take_ownership =
928 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
929 strcmp ((char *)m->gtktypes->data, "BOXED") == 0);
933 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
934 /* hack because glib is braindamaged */
935 set_func = g_strdup ("g_value_set_uint");
937 set_func = g_strdup_printf ("g_value_%s_%s",
940 (char *)m->gtktypes->data);
941 gob_strdown (set_func);
943 out_printf (out, "\n\t%s (return_value, v_return);\n",
948 if (no_gnu || for_cpp /* g++ has a cow with G_GNUC_UNUSED */) {
950 out_printf (out, "\n\treturn_value = NULL;\n");
951 out_printf (out, "\tinvocation_hint = NULL;\n");
954 out_printf (out, "}\n\n");
958 interface_type(const char *if_name)
960 char *rawtype = remove_sep(if_name);
961 char *end = "", *typename;
965 * EEEK! evil, we should have some sort of option
966 * to force this for arbitrary interfaces, since
967 * some are Class and some are Iface. Glib is shite
971 if (strcmp (rawtype, "GtkEditable") == 0
972 || strcmp (rawtype, "GTypePlugin") == 0)
976 /* We'll assume Iface is the standard ending */
980 /* GTK3 doesn't need Iface end */
984 typename = g_strconcat(rawtype, end, (char *)NULL);
991 define_parent_interface_refs(Class *c)
998 out_printf(out, "\n/* parent class interface implementations */\n");
999 for (li = c->interfaces; li != NULL; li = li->next) {
1000 char *name = replace_sep(li->data, '_');
1001 char *type = interface_type(li->data);
1003 out_printf (out, "static %s *%s_parent_iface;\n", type, name);
1014 out_printf(out, "\n");
1016 out_printf(out, "enum {\n");
1017 for(li=c->nodes;li;li=g_list_next(li)) {
1019 if(n->type == METHOD_NODE) {
1020 Method *m = (Method *)n;
1021 if(m->method == SIGNAL_LAST_METHOD ||
1022 m->method == SIGNAL_FIRST_METHOD) {
1023 char *s = g_strdup(m->id);
1025 out_printf(out, "\t%s_SIGNAL,\n", s);
1030 out_printf(out, "\tLAST_SIGNAL\n};\n\n");
1032 if (set_properties > 0 ||
1033 get_properties > 0) {
1034 out_printf(out, "enum {\n\tPROP_0");
1035 for(li=c->nodes;li;li=g_list_next(li)) {
1037 if (n->type == PROPERTY_NODE) {
1038 Property *p = (Property *)n;
1039 char *s = g_strdup (p->name);
1041 out_printf (out, ",\n\tPROP_%s", s);
1043 } else if (n->type == ARGUMENT_NODE) {
1044 Argument *a = (Argument *)n;
1045 char *s = g_strdup(a->name);
1047 out_printf(out, ",\n\tPROP_%s", s);
1051 out_printf(out, "\n};\n\n");
1056 "static guint object_signals[LAST_SIGNAL] = {0};\n\n");
1058 out_printf(out, "/* pointer to the class of our parent */\n");
1059 out_printf(out, "static %sClass *parent_class = NULL;\n", ptypebase);
1060 define_parent_interface_refs(c);
1061 out_printf(out, "\n");
1065 add_interface_methods (Class *c, const char *interface)
1068 gboolean added_line = FALSE;
1070 for (li = c->nodes; li != NULL; li = li->next) {
1072 Method *m = (Method *)n;
1073 if (n->type != METHOD_NODE ||
1074 m->method == OVERRIDE_METHOD ||
1075 m->interface == NULL ||
1076 strcmp (m->interface, interface) != 0)
1079 if (m->line_no > 0) {
1080 out_addline_infile (out, m->line_no);
1082 } else if (m->line_no == 0 &&
1084 out_addline_outfile (out);
1087 out_printf (out, "\tiface->%s = self_%s;\n",
1091 out_addline_outfile (out);
1095 add_interface_inits(Class *c)
1099 if (c->interfaces == NULL)
1102 out_printf(out, "\n");
1104 for (li = c->interfaces; li != NULL; li = li->next) {
1105 char *name = replace_sep(li->data, '_');
1106 char *type = interface_type(li->data);
1108 out_printf(out, "static void\n"
1109 "___%s_init (%s *iface)\n"
1112 add_interface_methods(c, li->data);
1114 out_printf(out, "\t%s_parent_iface\n", name);
1115 out_printf(out, for_cpp ? "\t\t= (%s *)" : "\t\t= ", type);
1116 out_printf(out, "g_type_interface_peek_parent(iface);\n"
1125 add_interface_infos(Class *c, gboolean static_storage)
1129 for (li = c->interfaces; li; li = li->next) {
1130 char *name = replace_sep(li->data, '_');
1131 out_printf(out, "\t%sconst GInterfaceInfo %s_info = {\n"
1132 "\t\t(GInterfaceInitFunc) ___%s_init,\n"
1136 static_storage ? "static " : "",
1141 out_printf(out, "\n");
1145 define_add_interfaces(Class *c)
1152 out_printf(out, "static void ___add_interfaces(GType type)\n{\n");
1153 add_interface_infos(c, TRUE);
1155 for (li = c->interfaces; li; li = li->next) {
1156 char *type = make_pre_macro(li->data, "TYPE");
1157 char *name = replace_sep(li->data, '_');
1159 out_printf(out, "\tg_type_add_interface_static\n"
1170 out_printf(out, "}\n\n");
1174 define_dynamic_add_interfaces(Class *c)
1181 out_printf(out, "static void ___add_interfaces"
1182 "(GTypeModule *type_module, GType type)\n"
1184 add_interface_infos(c, FALSE);
1187 * Hack to work around bug in g_type_module_add_interface,
1188 * which will fail to add an interface to types that derive
1189 * from something that also implements the same interface.
1191 * The actual GType system does not have any such problem,
1192 * and the GTypeModule implementation details relied upon
1193 * here have not changed once since the feature was first
1194 * implemented almost 20 years ago.
1196 out_printf(out, "\tstruct _ModuleInterfaceInfo {\n"
1197 "\t\tgboolean loaded;\n"
1198 "\t\tGType instance_type;\n"
1199 "\t\tGType interface_type;\n"
1200 "\t\tGInterfaceInfo info;\n"
1203 for (li = c->interfaces; li; li = li->next) {
1204 char *type = make_pre_macro(li->data, "TYPE");
1205 char *name = replace_sep(li->data, '_');
1207 out_printf(out, "\n"
1208 "\tmodinfo = g_malloc(sizeof *modinfo);\n"
1209 "\tmodinfo->loaded = TRUE;\n"
1210 "\tmodinfo->instance_type = type;\n"
1211 "\tmodinfo->interface_type = %s;\n"
1212 "\tmodinfo->info = %s_info;\n"
1213 "\tg_type_add_interface_dynamic\n"
1214 "\t\t( modinfo->instance_type\n"
1215 "\t\t, modinfo->interface_type\n"
1216 "\t\t, G_TYPE_PLUGIN(type_module)\n"
1218 "\ttype_module->interface_infos = g_slist_prepend\n"
1219 "\t\t( type_module->interface_infos\n"
1228 out_printf(out, "}\n\n");
1231 static void add_type_info(void)
1233 out_printf(out, "\tstatic const GTypeInfo info = {\n"
1234 "\t\tsizeof (%sClass),\n"
1235 "\t\t(GBaseInitFunc) NULL,\n"
1236 "\t\t(GBaseFinalizeFunc) NULL,\n"
1237 "\t\t(GClassInitFunc) %s_class_init,\n"
1238 "\t\t(GClassFinalizeFunc) NULL,\n"
1239 "\t\tNULL /* class_data */,\n"
1240 "\t\tsizeof (%s),\n"
1241 "\t\t%d /* n_preallocs */,\n"
1242 "\t\t(GInstanceInitFunc) %s_init,\n"
1245 typebase, funcbase, typebase, prealloc, funcbase);
1251 Class *c = (Class *)class;
1253 define_add_interfaces(c);
1255 out_printf(out, "GType %s_get_type(void)\n"
1257 "\tstatic GType type = 0;\n",
1262 out_printf(out, "\tif ___GOB_UNLIKELY(type == 0) {\n"
1263 "\t\ttype = g_type_register_static\n"
1267 "\t\t\t, (GTypeFlags)%s\n"
1269 pmacrotype, typebase,
1270 c->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0");
1273 out_printf(out, "\t\t___add_interfaces(type);\n");
1275 out_printf(out, "\t}\n\n"
1281 add_dynamic_get_type(void)
1283 Class *c = (Class *)class;
1285 define_dynamic_add_interfaces(c);
1287 out_printf(out, "static GType %s_type_id;\n\n"
1288 "GType %s_get_type(void)\n"
1290 "\treturn %s_type_id;\n"
1292 funcbase, funcbase, funcbase);
1294 out_printf(out, "void %s_register_type(GTypeModule *type_module)\n"
1300 out_printf(out, "\t%s_type_id = g_type_module_register_type\n"
1301 "\t\t( type_module\n"
1305 "\t\t, (GTypeFlags)%s\n"
1307 funcbase, pmacrotype, typebase,
1308 c->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0");
1310 if (c->interfaces) {
1311 out_printf(out, "\t___add_interfaces"
1312 "(type_module, %s_type_id);\n",
1316 out_printf(out, "}\n\n");
1320 add_bonobo_object_get_type(void)
1322 Class *c = (Class *)class;
1324 define_add_interfaces(c);
1326 out_printf (out, "GType %s_get_type(void)\n"
1328 "\tstatic GType type = 0;\n",
1333 out_printf (out, "\tif ___GOB_UNLIKELY(type == 0) {\n"
1334 "\t\ttype = bonobo_type_unique\n"
1335 "\t\t\t( BONOBO_OBJECT_TYPE\n"
1336 "\t\t\t, POA_%s__init, NULL\n"
1337 "\t\t\t, G_STRUCT_OFFSET (%sClass, _epv)\n"
1341 c->bonobo_object_class, typebase, typebase);
1343 if (((Class *)class)->interfaces)
1344 out_printf(out, "\t\t___add_interfaces(type);\n");
1346 out_printf(out, "\t}\n\n"
1352 add_overrides(Class *c, const char *oname,
1353 gboolean did_base_obj)
1359 done = g_hash_table_new (g_str_hash, g_str_equal);
1361 s = g_strdup ("GObject");
1362 g_hash_table_insert (done, s, s);
1364 for (li = c->nodes; li != NULL; li = li->next) {
1367 Method *m = (Method *)n;
1368 if(n->type != METHOD_NODE ||
1369 m->method != OVERRIDE_METHOD)
1372 s = remove_sep(m->otype);
1374 if(g_hash_table_lookup(done, s)) {
1378 g_hash_table_insert(done, s, s);
1380 f = replace_sep(m->otype, '_');
1383 out_printf(out, "\t%sClass *%s_class = (%sClass *)%s;\n",
1388 g_hash_table_foreach (done, (GHFunc)g_free, NULL);
1389 g_hash_table_destroy (done);
1393 make_run_signal_flags(Method *m, gboolean last)
1408 gs = g_string_new(NULL);
1411 g_string_assign(gs, "G_SIGNAL_RUN_LAST");
1413 g_string_assign(gs, "G_SIGNAL_RUN_FIRST");
1415 if(m->scope == PUBLIC_SCOPE)
1416 g_string_append(gs, " | G_SIGNAL_ACTION");
1418 for(li = m->flags; li; li = li->next) {
1419 char *flag = li->data;
1421 for(i=0;flags[i];i++) {
1422 if(strcmp(flags[i], flag)==0)
1425 /* if we haven't found it in our list */
1427 error_printf(GOB_WARN, m->line_no,
1428 "Unknown flag '%s' used, "
1429 "perhaps it was misspelled",
1432 g_string_sprintfa(gs, " | G_SIGNAL_%s", flag);
1436 char *ret = gs->str;
1437 g_string_free(gs, FALSE);
1444 add_signals(Class *c)
1448 out_printf(out, "\n");
1449 for(li=c->nodes;li;li=g_list_next(li)) {
1451 char *mar, *sig, *flags;
1452 gboolean is_none, last = FALSE;
1453 Method *m = (Method *)n;
1455 if(n->type != METHOD_NODE ||
1456 (m->method != SIGNAL_FIRST_METHOD &&
1457 m->method != SIGNAL_LAST_METHOD))
1460 if(m->method == SIGNAL_FIRST_METHOD)
1465 if(g_hash_table_lookup(marsh, m))
1466 mar = g_strconcat("___marshal_",
1467 (char *)g_hash_table_lookup(marsh, m),
1470 mar = g_strdup("g_cclosure_marshal_VOID__VOID");
1472 is_none = (strcmp(m->gtktypes->next->data, "NONE")==0);
1474 sig = g_strdup (m->id);
1476 flags = make_run_signal_flags (m, last);
1477 out_printf (out, "\tobject_signals[%s_SIGNAL] =\n"
1478 "\t\tg_signal_new (%s,\n"
1479 "\t\t\tG_TYPE_FROM_CLASS (g_object_class),\n"
1480 "\t\t\t(GSignalFlags)(%s),\n"
1481 "\t\t\tG_STRUCT_OFFSET (%sClass, %s),\n"
1482 "\t\t\tNULL, NULL,\n"
1484 "\t\t\tG_TYPE_%s, %d",
1485 sig, m->signal_name /*m->id* if not given signal_name*/,
1487 typebase, m->id, mar,
1488 (char *)m->gtktypes->data,
1489 is_none ? 0 : g_list_length(m->gtktypes->next));
1497 for(l = m->gtktypes->next; l != NULL; l = l->next) {
1498 char *str = l->data;
1499 if (strncmp (str, "BOXED_", 6) == 0)
1500 t = g_strdup (&(str[6]));
1502 t = g_strconcat ("G_TYPE_", str, NULL);
1503 out_printf (out, ",\n\t\t\t%s", t);
1508 out_printf(out, ");\n");
1510 if(strcmp(m->gtktypes->data, "NONE") != 0 ||
1513 out_printf(out, "\tif ___GOB_UNLIKELY(");
1514 if(strcmp(m->gtktypes->data, "NONE") != 0) {
1515 out_printf(out, "sizeof(");
1516 print_type(out, m->mtype, FALSE);
1517 out_printf(out, "%s",
1519 m->mtype->postfix : "");
1520 out_printf(out, ") != sizeof(%s) || ",
1521 get_cast(m->gtktypes->data, FALSE));
1524 for(al = m->args->next, gl = m->gtktypes->next;
1525 al != NULL && gl != NULL;
1526 al = al->next, gl = gl->next) {
1527 FuncArg *arg = al->data;
1528 char *gtkarg = gl->data;
1530 out_printf(out, "sizeof(");
1531 print_type(out, arg->atype, FALSE);
1532 out_printf(out, "%s",
1533 arg->atype->postfix ?
1534 arg->atype->postfix : "");
1535 out_printf(out, ") != sizeof(%s) || ",
1536 get_cast(gtkarg, FALSE));
1540 "parent_class == NULL /* avoid warning */");
1542 out_printf(out, ") {\n"
1543 "\t\tg_error(\"%s line %d: Type mismatch "
1544 "of \\\"%s\\\" signal signature\");\n"
1546 filename, m->line_no, m->id);
1553 set_def_handlers(Class *c, const char *oname)
1556 gboolean set_line = FALSE;
1558 out_printf(out, "\n");
1559 for(li = c->nodes; li; li = g_list_next(li)) {
1561 Method *m = (Method *)n;
1563 if(n->type != METHOD_NODE ||
1564 (m->method != SIGNAL_FIRST_METHOD &&
1565 m->method != SIGNAL_LAST_METHOD &&
1566 m->method != VIRTUAL_METHOD &&
1567 m->method != OVERRIDE_METHOD))
1570 if(m->line_no > 0 && m->cbuf) {
1571 out_addline_infile(out, m->line_no);
1573 } else if(set_line) {
1574 out_addline_outfile(out);
1579 if (m->method == OVERRIDE_METHOD) {
1581 s = replace_sep (m->otype, '_');
1585 dispose_handler != NULL &&
1586 strcmp (m->id, "dispose") == 0)
1587 out_printf (out, "\tg_object_class->dispose "
1589 else if (need_finalize &&
1591 strcmp(m->id, "finalize") == 0)
1593 "\tg_object_class->finalize = ___finalize;\n");
1594 else if (m->cbuf != NULL)
1596 "\t%s_class->%s = ___%x_%s_%s;\n",
1597 s, m->id, (guint)m->unique_id,
1600 out_printf(out, "\t%s_class->%s = NULL;\n",
1604 out_printf(out, "\t%s->%s = ___real_%s_%s;\n",
1608 out_printf(out, "\t%s->%s = NULL;\n",
1613 out_addline_outfile(out);
1617 make_argument (Argument *a)
1622 char *argflags[] = {
1630 flags = g_string_new ("(GParamFlags)(");
1632 if(a->get && a->set)
1633 g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
1635 g_string_append (flags, "G_PARAM_READABLE");
1637 g_string_append (flags, "G_PARAM_WRITABLE");
1639 g_assert(a->get || a->set);
1641 for (l = a->flags; l != NULL; l = l->next) {
1642 char *flag = l->data;
1644 if(strcmp (flag, "READABLE") == 0 ||
1645 strcmp (flag, "WRITABLE") == 0) {
1646 error_print(GOB_WARN, a->line_no,
1648 "WRITABLE argument flags are "
1649 "set automatically");
1652 for(i = 0; argflags[i]; i++) {
1653 if(strcmp(argflags[i], flag)==0)
1656 g_string_sprintfa(flags, " | %s%s", argflags[i] ? "G_PARAM_" : "", flag);
1659 g_string_append (flags, ")");
1661 s = g_strdup(a->name);
1663 if (!strcmp (a->gtktype, "ENUM"))
1664 out_printf(out, "\tparam_spec = g_param_spec_enum (\"%s\", NULL, NULL,\n"
1665 "\t\tG_TYPE_ENUM, 0,\n"
1667 a->name, flags->str);
1668 if (!strcmp (a->gtktype, "FLAGS"))
1669 out_printf(out, "\tparam_spec = g_param_spec_flags (\"%s\", NULL, NULL,\n"
1670 "\t\tG_TYPE_FLAGS, 0,\n"
1672 a->name, flags->str);
1673 else if (!strcmp (a->gtktype, "OBJECT"))
1674 out_printf(out, "\tparam_spec = g_param_spec_object (\"%s\", NULL, NULL,\n"
1675 "\t\tG_TYPE_OBJECT,\n"
1677 a->name, flags->str);
1678 else if (!strcmp (a->gtktype, "STRING"))
1679 out_printf(out, "\tparam_spec = g_param_spec_string (\"%s\", NULL, NULL,\n"
1682 a->name, flags->str);
1683 else if (!strcmp (a->gtktype, "INT"))
1684 out_printf(out, "\tparam_spec = g_param_spec_int (\"%s\", NULL, NULL,\n"
1685 "\t\tG_MININT, G_MAXINT,\n"
1688 a->name, flags->str);
1689 else if (!strcmp (a->gtktype, "UINT"))
1690 out_printf(out, "\tparam_spec = g_param_spec_uint (\"%s\", NULL, NULL,\n"
1691 "\t\t0, G_MAXUINT,\n"
1694 a->name, flags->str);
1695 else if (!strcmp (a->gtktype, "INT"))
1696 out_printf(out, "\tparam_spec = g_param_spec_int (\"%s\", NULL, NULL,\n"
1697 "\t\tG_MININT, G_MAXINT,\n"
1700 a->name, flags->str);
1701 else if (!strcmp (a->gtktype, "CHAR"))
1702 out_printf(out, "\tparam_spec = g_param_spec_char (\"%s\", NULL, NULL,\n"
1706 a->name, flags->str);
1707 else if (!strcmp (a->gtktype, "UCHAR"))
1708 out_printf(out, "\tparam_spec = g_param_spec_uchar (\"%s\", NULL, NULL,\n"
1712 a->name, flags->str);
1713 else if (!strcmp (a->gtktype, "BOOL") ||
1714 !strcmp (a->gtktype, "BOOLEAN"))
1715 out_printf(out, "\tparam_spec = g_param_spec_boolean (\"%s\", NULL, NULL,\n"
1718 a->name, flags->str);
1719 else if (!strcmp (a->gtktype, "LONG"))
1720 out_printf(out, "\tparam_spec = g_param_spec_long (\"%s\", NULL, NULL,\n"
1721 "\t\tG_MINLONG, G_MAXLONG,\n"
1724 a->name, flags->str);
1725 else if (!strcmp (a->gtktype, "ULONG"))
1726 out_printf(out, "\tparam_spec = g_param_spec_ulong (\"%s\", NULL, NULL,\n"
1727 "\t\t0, G_MAXULONG,\n"
1730 a->name, flags->str);
1731 else if (!strcmp (a->gtktype, "INT64"))
1732 out_printf(out, "\tparam_spec = g_param_spec_int64 (\"%s\", NULL, NULL,\n"
1733 "\t\tG_MININT64, G_MAXINT64,\n"
1736 a->name, flags->str);
1737 else if (!strcmp (a->gtktype, "UINT64"))
1738 out_printf(out, "\tparam_spec = g_param_spec_uint64 (\"%s\", NULL, NULL,\n"
1739 "\t\t0, G_MAXUINT64,\n"
1742 a->name, flags->str);
1743 else if (!strcmp (a->gtktype, "FLOAT"))
1744 out_printf(out, "\tparam_spec = g_param_spec_float (\"%s\", NULL, NULL,\n"
1745 "\t\t-G_MAXFLOAT, G_MAXFLOAT,\n"
1748 a->name, flags->str);
1749 else if (!strcmp (a->gtktype, "DOUBLE"))
1750 out_printf(out, "\tparam_spec = g_param_spec_double (\"%s\", NULL, NULL,\n"
1751 "\t\t-G_MAXDOUBLE, G_MAXDOUBLE,\n"
1754 a->name, flags->str);
1755 else if (!strcmp (a->gtktype, "POINTER"))
1756 out_printf(out, "\tparam_spec = g_param_spec_pointer (\"%s\", NULL, NULL,\n"
1758 a->name, flags->str);
1760 error_printf (GOB_ERROR, a->line_no,
1761 "%s type is not supported for arguments, try using properties",
1764 out_printf(out, "\tg_object_class_install_property (g_object_class,\n"
1765 "\t\tPROP_%s, param_spec);\n", s);
1769 g_string_free(flags, TRUE);
1772 #define value_for_print(str, alt) (str != NULL ? str : alt)
1775 make_property (Property *p)
1779 if (p->get == NULL && p->set == NULL) {
1780 error_print (GOB_ERROR, p->line_no,
1781 "Property has no getter nor setter");
1785 if (p->flags != NULL)
1786 error_print (GOB_WARN, p->line_no,
1787 "Overridden property, flags ignored");
1788 if (p->nick != NULL)
1789 error_print (GOB_WARN, p->line_no,
1790 "Overridden property, nick ignored");
1791 if (p->blurb != NULL)
1792 error_print (GOB_WARN, p->line_no,
1793 "Overridden property, blurb ignored");
1794 if (p->minimum != NULL)
1795 error_print (GOB_WARN, p->line_no,
1796 "Overridden property, minimum ignored");
1797 if (p->maximum != NULL)
1798 error_print (GOB_WARN, p->line_no,
1799 "Overridden property, maximum ignored");
1800 if (p->default_value != NULL)
1801 error_print (GOB_WARN, p->line_no,
1802 "Overridden property, default_value ignored");
1804 s = g_strdup (p->name);
1806 out_printf (out, "\tg_object_class_override_property (g_object_class,\n"
1808 "\t\t\"%s\");\n", s, value_for_print (p->canonical_name, p->name) );
1813 char *argflags[] = {
1821 flags = g_string_new ("(GParamFlags)(");
1823 if (p->get != NULL && p->set != NULL)
1824 g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
1825 else if (p->get != NULL)
1826 g_string_append (flags, "G_PARAM_READABLE");
1828 g_string_append (flags, "G_PARAM_WRITABLE");
1831 for (l = p->flags; l != NULL; l = l->next) {
1832 char *flag = l->data;
1834 if(strcmp (flag, "READABLE") == 0 ||
1835 strcmp (flag, "WRITABLE") == 0) {
1836 error_print(GOB_WARN, p->line_no,
1838 "WRITABLE argument flags are "
1839 "set automatically");
1842 for(i = 0; argflags[i]; i++) {
1843 if(strcmp(argflags[i], flag)==0)
1846 g_string_sprintfa(flags, " | %s%s", argflags[i] ? "G_PARAM_" : "", flag);
1849 g_string_append (flags, ")");
1851 if (strcmp (p->gtktype, "CHAR") == 0) {
1852 out_printf (out, "\tparam_spec = g_param_spec_char\n"
1853 "\t\t(\"%s\" /* name */,\n"
1854 "\t\t %s /* nick */,\n"
1855 "\t\t %s /* blurb */,\n"
1856 "\t\t %s /* minimum */,\n"
1857 "\t\t %s /* maximum */,\n"
1858 "\t\t %s /* default_value */,\n"
1860 value_for_print (p->canonical_name, p->name),
1861 value_for_print (p->nick, "NULL"),
1862 value_for_print (p->blurb, "NULL"),
1863 value_for_print (p->minimum, "-128"),
1864 value_for_print (p->maximum, "127"),
1865 value_for_print (p->default_value, "0"),
1867 } else if (strcmp (p->gtktype, "UCHAR") == 0) {
1868 out_printf (out, "\tparam_spec = g_param_spec_uchar\n"
1869 "\t\t(\"%s\" /* name */,\n"
1870 "\t\t %s /* nick */,\n"
1871 "\t\t %s /* blurb */,\n"
1872 "\t\t %s /* minimum */,\n"
1873 "\t\t %s /* maximum */,\n"
1874 "\t\t %s /* default_value */,\n"
1876 value_for_print (p->canonical_name, p->name),
1877 value_for_print (p->nick, "NULL"),
1878 value_for_print (p->blurb, "NULL"),
1879 value_for_print (p->minimum, "0"),
1880 value_for_print (p->maximum, "0xFF"),
1881 value_for_print (p->default_value, "0"),
1883 } else if (strcmp (p->gtktype, "BOOLEAN") == 0) {
1884 out_printf (out, "\tparam_spec = g_param_spec_boolean\n"
1885 "\t\t(\"%s\" /* name */,\n"
1886 "\t\t %s /* nick */,\n"
1887 "\t\t %s /* blurb */,\n"
1888 "\t\t %s /* default_value */,\n"
1890 value_for_print (p->canonical_name, p->name),
1891 value_for_print (p->nick, "NULL"),
1892 value_for_print (p->blurb, "NULL"),
1893 value_for_print (p->default_value, "FALSE"),
1895 } else if (strcmp (p->gtktype, "INT") == 0) {
1896 out_printf (out, "\tparam_spec = g_param_spec_int\n"
1897 "\t\t(\"%s\" /* name */,\n"
1898 "\t\t %s /* nick */,\n"
1899 "\t\t %s /* blurb */,\n"
1900 "\t\t %s /* minimum */,\n"
1901 "\t\t %s /* maximum */,\n"
1902 "\t\t %s /* default_value */,\n"
1904 value_for_print (p->canonical_name, p->name),
1905 value_for_print (p->nick, "NULL"),
1906 value_for_print (p->blurb, "NULL"),
1907 value_for_print (p->minimum, "G_MININT"),
1908 value_for_print (p->maximum, "G_MAXINT"),
1909 value_for_print (p->default_value, "0"),
1911 } else if (strcmp (p->gtktype, "UINT") == 0) {
1912 out_printf (out, "\tparam_spec = g_param_spec_uint\n"
1913 "\t\t(\"%s\" /* name */,\n"
1914 "\t\t %s /* nick */,\n"
1915 "\t\t %s /* blurb */,\n"
1916 "\t\t %s /* minimum */,\n"
1917 "\t\t %s /* maximum */,\n"
1918 "\t\t %s /* default_value */,\n"
1920 value_for_print (p->canonical_name, p->name),
1921 value_for_print (p->nick, "NULL"),
1922 value_for_print (p->blurb, "NULL"),
1923 value_for_print (p->minimum, "0"),
1924 value_for_print (p->maximum, "G_MAXUINT"),
1925 value_for_print (p->default_value, "0"),
1927 } else if (strcmp (p->gtktype, "LONG") == 0) {
1928 out_printf (out, "\tparam_spec = g_param_spec_long\n"
1929 "\t\t(\"%s\" /* name */,\n"
1930 "\t\t %s /* nick */,\n"
1931 "\t\t %s /* blurb */,\n"
1932 "\t\t %s /* minimum */,\n"
1933 "\t\t %s /* maximum */,\n"
1934 "\t\t %s /* default_value */,\n"
1936 value_for_print (p->canonical_name, p->name),
1937 value_for_print (p->nick, "NULL"),
1938 value_for_print (p->blurb, "NULL"),
1939 value_for_print (p->minimum, "G_MINLONG"),
1940 value_for_print (p->maximum, "G_MAXLONG"),
1941 value_for_print (p->default_value, "0"),
1943 } else if (strcmp (p->gtktype, "ULONG") == 0) {
1944 out_printf (out, "\tparam_spec = g_param_spec_ulong\n"
1945 "\t\t(\"%s\" /* name */,\n"
1946 "\t\t %s /* nick */,\n"
1947 "\t\t %s /* blurb */,\n"
1948 "\t\t %s /* minimum */,\n"
1949 "\t\t %s /* maximum */,\n"
1950 "\t\t %s /* default_value */,\n"
1952 value_for_print (p->canonical_name, p->name),
1953 value_for_print (p->nick, "NULL"),
1954 value_for_print (p->blurb, "NULL"),
1955 value_for_print (p->minimum, "0"),
1956 value_for_print (p->maximum, "G_MAXULONG"),
1957 value_for_print (p->default_value, "0"),
1959 } else if (strcmp (p->gtktype, "INT64") == 0) {
1960 out_printf (out, "\tparam_spec = g_param_spec_int64\n"
1961 "\t\t(\"%s\" /* name */,\n"
1962 "\t\t %s /* nick */,\n"
1963 "\t\t %s /* blurb */,\n"
1964 "\t\t %s /* minimum */,\n"
1965 "\t\t %s /* maximum */,\n"
1966 "\t\t %s /* default_value */,\n"
1968 value_for_print (p->canonical_name, p->name),
1969 value_for_print (p->nick, "NULL"),
1970 value_for_print (p->blurb, "NULL"),
1971 value_for_print (p->minimum, "G_MININT64"),
1972 value_for_print (p->maximum, "G_MAXINT64"),
1973 value_for_print (p->default_value, "0"),
1975 } else if (strcmp (p->gtktype, "UINT64") == 0) {
1976 out_printf (out, "\tparam_spec = g_param_spec_uint64\n"
1977 "\t\t(\"%s\" /* name */,\n"
1978 "\t\t %s /* nick */,\n"
1979 "\t\t %s /* blurb */,\n"
1980 "\t\t %s /* minimum */,\n"
1981 "\t\t %s /* maximum */,\n"
1982 "\t\t %s /* default_value */,\n"
1984 value_for_print (p->canonical_name, p->name),
1985 value_for_print (p->nick, "NULL"),
1986 value_for_print (p->blurb, "NULL"),
1987 value_for_print (p->minimum, "0"),
1988 value_for_print (p->maximum, "G_MAXUINT64"),
1989 value_for_print (p->default_value, "0"),
1991 } else if (strcmp (p->gtktype, "UNICHAR") == 0) {
1992 out_printf (out, "\tparam_spec = g_param_spec_unichar\n"
1993 "\t\t(\"%s\" /* name */,\n"
1994 "\t\t %s /* nick */,\n"
1995 "\t\t %s /* blurb */,\n"
1996 "\t\t %s /* default_value */,\n"
1998 value_for_print (p->canonical_name, p->name),
1999 value_for_print (p->nick, "NULL"),
2000 value_for_print (p->blurb, "NULL"),
2001 value_for_print (p->default_value, "0"),
2003 } else if (strcmp (p->gtktype, "ENUM") == 0) {
2004 char *type = make_me_type (p->extra_gtktype,
2006 out_printf (out, "\tparam_spec = g_param_spec_enum\n"
2007 "\t\t(\"%s\" /* name */,\n"
2008 "\t\t %s /* nick */,\n"
2009 "\t\t %s /* blurb */,\n"
2010 "\t\t %s /* enum_type */,\n"
2011 "\t\t %s /* default_value */,\n"
2013 value_for_print (p->canonical_name, p->name),
2014 value_for_print (p->nick, "NULL"),
2015 value_for_print (p->blurb, "NULL"),
2017 value_for_print (p->default_value, "0"),
2020 } else if (strcmp (p->gtktype, "FLAGS") == 0) {
2021 char *type = make_me_type (p->extra_gtktype,
2023 out_printf (out, "\tparam_spec = g_param_spec_flags\n"
2024 "\t\t(\"%s\" /* name */,\n"
2025 "\t\t %s /* nick */,\n"
2026 "\t\t %s /* blurb */,\n"
2027 "\t\t %s /* flags_type */,\n"
2028 "\t\t %s /* default_value */,\n"
2030 value_for_print (p->canonical_name, p->name),
2031 value_for_print (p->nick, "NULL"),
2032 value_for_print (p->blurb, "NULL"),
2034 value_for_print (p->default_value, "0"),
2037 } else if (strcmp (p->gtktype, "FLOAT") == 0) {
2038 out_printf (out, "\tparam_spec = g_param_spec_float\n"
2039 "\t\t(\"%s\" /* name */,\n"
2040 "\t\t %s /* nick */,\n"
2041 "\t\t %s /* blurb */,\n"
2042 "\t\t %s /* minimum */,\n"
2043 "\t\t %s /* maximum */,\n"
2044 "\t\t %s /* default_value */,\n"
2046 value_for_print (p->canonical_name, p->name),
2047 value_for_print (p->nick, "NULL"),
2048 value_for_print (p->blurb, "NULL"),
2049 value_for_print (p->minimum, "-G_MAXFLOAT"),
2050 value_for_print (p->maximum, "G_MAXFLOAT"),
2051 value_for_print (p->default_value, "0.0"),
2053 } else if (strcmp (p->gtktype, "DOUBLE") == 0) {
2054 out_printf (out, "\tparam_spec = g_param_spec_double\n"
2055 "\t\t(\"%s\" /* name */,\n"
2056 "\t\t %s /* nick */,\n"
2057 "\t\t %s /* blurb */,\n"
2058 "\t\t %s /* minimum */,\n"
2059 "\t\t %s /* maximum */,\n"
2060 "\t\t %s /* default_value */,\n"
2062 value_for_print (p->canonical_name, p->name),
2063 value_for_print (p->nick, "NULL"),
2064 value_for_print (p->blurb, "NULL"),
2065 value_for_print (p->minimum, "-G_MAXDOUBLE"),
2066 value_for_print (p->maximum, "G_MAXDOUBLE"),
2067 value_for_print (p->default_value, "0.0"),
2069 } else if (strcmp (p->gtktype, "STRING") == 0) {
2070 out_printf (out, "\tparam_spec = g_param_spec_string\n"
2071 "\t\t(\"%s\" /* name */,\n"
2072 "\t\t %s /* nick */,\n"
2073 "\t\t %s /* blurb */,\n"
2074 "\t\t %s /* default_value */,\n"
2076 value_for_print (p->canonical_name, p->name),
2077 value_for_print (p->nick, "NULL"),
2078 value_for_print (p->blurb, "NULL"),
2079 value_for_print (p->default_value, "NULL"),
2081 } else if (strcmp (p->gtktype, "PARAM") == 0) {
2082 char *type = make_me_type (p->extra_gtktype,
2084 out_printf (out, "\tparam_spec = g_param_spec_param\n"
2085 "\t\t(\"%s\" /* name */,\n"
2086 "\t\t %s /* nick */,\n"
2087 "\t\t %s /* blurb */,\n"
2088 "\t\t %s /* param_type */,\n"
2090 value_for_print (p->canonical_name, p->name),
2091 value_for_print (p->nick, "NULL"),
2092 value_for_print (p->blurb, "NULL"),
2096 } else if (strcmp (p->gtktype, "BOXED") == 0) {
2097 char *type = make_me_type (p->extra_gtktype,
2099 out_printf (out, "\tparam_spec = g_param_spec_boxed\n"
2100 "\t\t(\"%s\" /* name */,\n"
2101 "\t\t %s /* nick */,\n"
2102 "\t\t %s /* blurb */,\n"
2103 "\t\t %s /* boxed_type */,\n"
2105 value_for_print (p->canonical_name, p->name),
2106 value_for_print (p->nick, "NULL"),
2107 value_for_print (p->blurb, "NULL"),
2111 } else if (strcmp (p->gtktype, "POINTER") == 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 /* FIXME: VALUE_ARRAY */
2122 } else if (strcmp (p->gtktype, "CLOSURE") == 0) {
2123 out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
2124 "\t\t(\"%s\" /* name */,\n"
2125 "\t\t %s /* nick */,\n"
2126 "\t\t %s /* blurb */,\n"
2128 value_for_print (p->canonical_name, p->name),
2129 value_for_print (p->nick, "NULL"),
2130 value_for_print (p->blurb, "NULL"),
2132 } else if (strcmp (p->gtktype, "OBJECT") == 0) {
2133 char *type = make_me_type (p->extra_gtktype,
2135 out_printf (out, "\tparam_spec = g_param_spec_object\n"
2136 "\t\t(\"%s\" /* name */,\n"
2137 "\t\t %s /* nick */,\n"
2138 "\t\t %s /* blurb */,\n"
2139 "\t\t %s /* object_type */,\n"
2141 value_for_print (p->canonical_name, p->name),
2142 value_for_print (p->nick, "NULL"),
2143 value_for_print (p->blurb, "NULL"),
2148 error_printf (GOB_ERROR, p->line_no,
2149 "%s type is not supported by properties",
2153 s = g_strdup (p->name);
2155 out_printf (out, "\tg_object_class_install_property (g_object_class,\n"
2157 "\t\tparam_spec);\n", s);
2160 g_string_free (flags, TRUE);
2165 make_arguments(Class *c)
2168 if (get_properties > 0)
2169 out_printf(out, "\tg_object_class->get_property = ___object_get_property;\n");
2170 if (set_properties > 0)
2171 out_printf(out, "\tg_object_class->set_property = ___object_set_property;\n");
2172 out_printf (out, " {\n");
2173 for (li = c->nodes; li != NULL; li = li->next) {
2175 if ((n->type == PROPERTY_NODE && ! ((Property *) n)->override)
2176 || n->type == ARGUMENT_NODE) {
2177 out_printf(out, "\tGParamSpec *param_spec;\n\n");
2182 for (li = c->nodes; li != NULL; li = li->next) {
2184 if (n->type == PROPERTY_NODE)
2185 make_property ((Property *)n);
2186 else if (n->type == ARGUMENT_NODE)
2187 make_argument ((Argument *)n);
2189 out_printf(out, " }\n");
2193 print_initializer(Method *m, Variable *v)
2200 if(v->initializer == NULL)
2203 if(v->scope == PRIVATE_SCOPE)
2204 root = g_strconcat(((FuncArg *)m->args->data)->name,
2207 root = g_strdup(((FuncArg *)m->args->data)->name);
2209 if(v->initializer_line > 0)
2210 out_addline_infile(out, v->initializer_line);
2212 if (v->initializer_simple)
2213 out_printf(out, "\t%s->%s = %s;\n",
2214 root, v->id, v->initializer);
2215 else if (strcmp(v->id, "_glade_xml") == 0)
2216 /* This is OK, this v->initializer string is set internally
2217 and it will eat exactly one string! */
2218 out_printf(out,v->initializer, ((FuncArg *)m->args->data)->name);
2220 out_printf(out, "%s", v->initializer);
2222 if(v->initializer_line > 0)
2223 out_addline_outfile(out);
2229 print_glade_widget(Method *m, Variable *v)
2234 if(!v->glade_widget)
2237 if(v->scope == PRIVATE_SCOPE)
2238 root = g_strconcat(((FuncArg *)m->args->data)->name,
2241 root = g_strdup(((FuncArg *)m->args->data)->name);
2243 cast = get_type(v->vtype, FALSE);
2244 out_printf(out, "\t%s->%s = (%s)glade_xml_get_widget(%s->_glade_xml, \"%s\");\n",
2245 root, v->id, cast, root, v->id);
2251 print_destructor (Variable *v)
2255 if(v->destructor == NULL)
2258 if(v->scope == PRIVATE_SCOPE)
2259 root = "self->_priv";
2263 if(v->destructor_simple) {
2264 if(v->destructor_line > 0)
2265 out_addline_infile(out, v->destructor_line);
2268 out_printf(out, "\tif(%s->%s) { "
2269 "(reinterpret_cast<void (*)(void *)>(%s)) ((gpointer)%s->%s); "
2270 "%s->%s = NULL; }\n",
2271 root, v->id, v->destructor, root, v->id,
2274 out_printf(out, "\tif(%s->%s) { "
2275 "%s ((gpointer) %s->%s); "
2276 "%s->%s = NULL; }\n",
2277 root, v->id, v->destructor, root, v->id,
2281 if(v->destructor_line > 0)
2282 out_addline_outfile(out);
2284 out_printf(out, "#define %s (%s->%s)\n", v->id, root, v->id);
2285 out_printf(out, "#define VAR %s\n", v->id);
2286 out_printf(out, "\t{\n");
2287 if(v->destructor_line > 0)
2288 out_addline_infile(out, v->destructor_line);
2290 out_printf(out, "\t%s}\n", v->destructor);
2292 if(v->destructor_line > 0)
2293 out_addline_outfile(out);
2294 out_printf(out, "\tmemset(&(%s), 0, sizeof(%s));\n",
2296 out_printf(out, "#undef VAR\n");
2297 out_printf(out, "#undef %s\n", v->id);
2302 add_constructor (Class *c)
2304 out_printf(out, "\nstatic GObject *\n"
2305 "___constructor (GType type, guint n_construct_properties, GObjectConstructParam *construct_properties)\n"
2308 "#define __GOB_FUNCTION__ \"%s::constructor\"\n",
2311 out_printf(out, "\tGObject *obj_self;\n");
2312 out_printf(out, "\t%s *self;\n", typebase);
2314 out_printf(out, "\tobj_self = G_OBJECT_CLASS (parent_class)->constructor (type, n_construct_properties, construct_properties);\n");
2315 out_printf(out, "\tself = %s (obj_self);\n", macrobase);
2317 if (user_constructor->line_no > 0)
2318 out_addline_infile (out, user_constructor->line_no);
2319 out_printf (out, "\t%s_constructor (self);\n", funcbase);
2320 if (user_constructor->line_no > 0)
2321 out_addline_outfile (out);
2323 out_printf(out, "\treturn obj_self;\n");
2324 out_printf(out, "}\n"
2325 "#undef __GOB_FUNCTION__\n\n");
2329 print_unreftors (Class *c)
2332 for(li = ((Class *)class)->nodes;
2336 Variable *v = (Variable *)n;
2337 if (n->type == VARIABLE_NODE &&
2338 v->scope != CLASS_SCOPE &&
2339 v->destructor_unref)
2340 print_destructor (v);
2345 add_dispose (Class *c)
2347 out_printf(out, "\nstatic void\n"
2348 "___dispose (GObject *obj_self)\n"
2351 "#define __GOB_FUNCTION__ \"%s::dispose\"\n",
2354 if (unreftors > 0 || user_dispose_method != NULL) {
2355 out_printf (out, "\t%s *self%s = %s (obj_self);\n",
2357 ! no_gnu ? " G_GNUC_UNUSED" : "",
2361 if (dispose_handler != NULL) {
2362 if (unreftors > 0) {
2363 print_unreftors (c);
2366 /* so we get possible bad argument warning */
2367 if (dispose_handler->line_no > 0)
2368 out_addline_infile (out, dispose_handler->line_no);
2369 out_printf (out, "\t___%x_%s_dispose(obj_self);\n",
2370 (guint)dispose_handler->unique_id, funcbase);
2371 if (dispose_handler->line_no > 0)
2372 out_addline_outfile (out);
2374 if (user_dispose_method != NULL) {
2375 if (user_dispose_method->line_no > 0)
2376 out_addline_infile (out, user_dispose_method->line_no);
2377 out_printf (out, "\t%s_dispose (self);\n", funcbase);
2378 if (user_dispose_method->line_no > 0)
2379 out_addline_outfile (out);
2382 if (unreftors > 0) {
2383 print_unreftors (c);
2387 "\tif (G_OBJECT_CLASS (parent_class)->dispose) \\\n"
2388 "\t\t(* G_OBJECT_CLASS (parent_class)->dispose) (obj_self);\n");
2391 out_printf(out, "}\n"
2392 "#undef __GOB_FUNCTION__\n\n");
2396 print_destructors (Class *c)
2399 for (li = ((Class *)class)->nodes;
2403 Variable *v = (Variable *)n;
2404 if (n->type == VARIABLE_NODE &&
2405 v->scope != CLASS_SCOPE &&
2406 ! v->destructor_unref)
2407 print_destructor (v);
2412 add_finalize (Class *c)
2416 "___finalize(GObject *obj_self)\n"
2419 "#define __GOB_FUNCTION__ \"%s::finalize\"\n",
2424 user_finalize_method != NULL) {
2425 const char *unused = "";
2427 unused = " G_GNUC_UNUSED";
2428 out_printf(out, "\t%s *self%s = %s (obj_self);\n",
2429 typebase, unused, macrobase);
2432 const char *unused = "";
2434 unused = " G_GNUC_UNUSED";
2435 out_printf(out, "\tgpointer priv%s = self->_priv;\n",
2439 if(finalize_handler) {
2440 if (destructors > 0) {
2441 print_destructors (c);
2444 /* so we get possible bad argument warning */
2445 if(finalize_handler->line_no > 0)
2446 out_addline_infile(out, finalize_handler->line_no);
2447 out_printf(out, "\t___%x_%s_finalize(obj_self);\n",
2448 (guint)finalize_handler->unique_id, funcbase);
2449 if(finalize_handler->line_no > 0)
2450 out_addline_outfile(out);
2452 if (user_finalize_method != NULL) {
2453 if (user_finalize_method->line_no > 0)
2454 out_addline_infile (out, user_finalize_method->line_no);
2455 out_printf (out, "\t%s_finalize (self);\n", funcbase);
2456 if (user_finalize_method->line_no > 0)
2457 out_addline_outfile (out);
2460 if (destructors > 0) {
2461 print_destructors (c);
2465 "\tif(G_OBJECT_CLASS(parent_class)->finalize) \\\n"
2466 "\t\t(* G_OBJECT_CLASS(parent_class)->finalize)(obj_self);\n");
2469 out_printf(out, "}\n"
2470 "#undef __GOB_FUNCTION__\n\n");
2474 make_bonobo_object_epv (Class *c, const char *classname)
2477 gboolean added_line = FALSE;
2479 for (li = c->nodes; li != NULL; li = li->next) {
2481 Method *m = (Method *)n;
2482 if(n->type != METHOD_NODE ||
2483 m->method == OVERRIDE_METHOD)
2486 if (m->bonobo_object_func) {
2487 if(m->line_no > 0) {
2488 out_addline_infile(out, m->line_no);
2490 } else if (m->line_no == 0 &&
2492 out_addline_outfile(out);
2495 out_printf (out, "\t%s->_epv.%s = self_%s;\n",
2496 classname, m->id, m->id);
2500 out_addline_outfile(out);
2506 const char *unused = "";
2510 unused = " G_GNUC_UNUSED";
2512 for(li=c->nodes;li;li=g_list_next(li)) {
2516 if(n->type != METHOD_NODE)
2519 if(m->method == INIT_METHOD) {
2521 out_addline_infile(out, m->line_no);
2522 print_method(out, "static ", "\n", "", " ", "", "\n",
2523 m, FALSE, FALSE, FALSE, TRUE, TRUE,
2525 out_printf(out, "{\n");
2527 out_addline_outfile(out);
2529 "#define __GOB_FUNCTION__ \"%s::init\"\n",
2532 out_printf(out, "\t%s->_priv = "
2533 "G_TYPE_INSTANCE_GET_PRIVATE(%s,%s,%sPrivate);\n",
2534 ((FuncArg *)m->args->data)->name,
2535 ((FuncArg *)m->args->data)->name,
2538 } else if(always_private_struct) {
2539 out_printf(out, "\t%s->_priv = NULL;\n",
2540 ((FuncArg *)m->args->data)->name);
2542 if(initializers > 0) {
2544 for(li = ((Class *)class)->nodes;
2548 Variable *v = (Variable *)n;
2549 if(n->type != VARIABLE_NODE ||
2550 v->scope == CLASS_SCOPE)
2552 print_initializer(m, v);
2555 if(glade_widgets > 0) {
2557 for(li = ((Class *)class)->nodes;
2561 Variable *v = (Variable *)n;
2562 if(n->type != VARIABLE_NODE ||
2563 v->scope == CLASS_SCOPE)
2565 print_glade_widget(m, v);
2568 } else if(m->method == CLASS_INIT_METHOD) {
2569 gboolean did_base_obj = FALSE;
2572 out_addline_infile(out, m->line_no);
2573 print_method(out, "static ", "\n", "", " ", "", "\n",
2574 m, FALSE, FALSE, FALSE, TRUE, TRUE,
2576 out_printf(out, "{\n");
2578 out_addline_outfile(out);
2580 "#define __GOB_FUNCTION__ \"%s::class_init\"\n",
2582 if (set_properties > 0 ||
2583 get_properties > 0 ||
2590 "g_object_class%s = "
2591 "(GObjectClass*) %s;\n",
2593 ((FuncArg *)m->args->data)->name);
2594 did_base_obj = TRUE;
2599 ((FuncArg *)m->args->data)->name,
2604 "\n\tg_type_class_add_private(%s,sizeof(%sPrivate));\n",
2605 ((FuncArg *)m->args->data)->name,
2608 if (initializers > 0) {
2610 for(li = ((Class *)class)->nodes;
2614 Variable *v = (Variable *)n;
2615 if(n->type == VARIABLE_NODE &&
2616 v->scope == CLASS_SCOPE)
2617 print_initializer(m, v);
2621 out_printf(out, "\n\tparent_class = ");
2623 out_printf(out, "(%sClass *)", ptypebase);
2624 out_printf(out, "g_type_class_ref (%s);\n",
2630 set_def_handlers(c, ((FuncArg *)m->args->data)->name);
2632 /* if there are no handlers for these things, we
2633 * need to set them up here */
2634 if(need_constructor)
2635 out_printf(out, "\tg_object_class->constructor "
2636 "= ___constructor;\n");
2637 if(need_dispose && !dispose_handler)
2638 out_printf(out, "\tg_object_class->dispose "
2640 if(need_finalize && !finalize_handler)
2641 out_printf(out, "\tg_object_class->finalize = "
2644 if(get_properties > 0 || set_properties > 0)
2647 if (c->bonobo_object_class != NULL) {
2648 make_bonobo_object_epv (c, ((FuncArg *)m->args->data)->name);
2654 out_printf(out, " {\n");
2655 out_addline_infile(out, m->ccode_line);
2656 out_printf(out, "%s\n", m->cbuf);
2657 out_addline_outfile(out);
2658 out_printf(out, " }\n");
2660 out_printf(out, "}\n"
2661 "#undef __GOB_FUNCTION__\n");
2666 add_argument (Argument *a, gboolean is_set)
2670 char *the_type_lower;
2675 line_no = a->set_line;
2678 line_no = a->get_line;
2682 s = g_strdup(a->name);
2684 out_printf(out, "\tcase PROP_%s:\n\t{", s);
2686 the_type_lower = g_strdup (a->gtktype);
2687 gob_strdown (the_type_lower);
2689 /* HACK because there is no g_value_set/get for unichar */
2690 if (strcmp (the_type_lower, "unichar") == 0) {
2691 g_free (the_type_lower);
2692 the_type_lower = g_strdup ("uint");
2697 const char *unused = "";
2699 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
2700 unused = " G_GNUC_UNUSED";
2703 if (a->atype != NULL &&
2704 /* gcc -Wbad-function-cast is wanking stupid, moronic
2705 and otherwise evil so we should just use a (gint)
2706 or (guint) cast, not the specific type cast */
2708 (strcmp (a->gtktype, "ENUM") != 0 &&
2709 strcmp (a->gtktype, "FLAGS") != 0)))
2710 cast = get_type (a->atype, TRUE);
2712 cast = g_strdup (get_cast (a->gtktype, FALSE));
2714 out_printf (out, "\t%s ARG%s = (%s) g_value_get_%s (VAL);\n",
2715 cast, unused, cast, the_type_lower);
2718 } else if ( ! is_set) {
2721 if (a->atype != NULL)
2722 cast = get_type (a->atype, TRUE);
2724 cast = g_strdup (get_cast (a->gtktype, FALSE));
2725 out_printf (out, "\t%s ARG;\n"
2726 "\tmemset (&ARG, 0, sizeof (%s));\n",
2732 out_printf(out, "\t\t{\n");
2734 out_addline_infile (out, line_no);
2735 out_printf (out, "%s\n", cbuf);
2737 out_addline_outfile (out);
2738 out_printf (out, "\t\t}\n");
2740 if (strcmp (a->gtktype, "OBJECT") == 0)
2741 out_printf (out, "\t\tg_value_set_%s (VAL, G_OBJECT (ARG));\n",
2744 out_printf (out, "\t\t"
2745 "g_value_set_%s (VAL, ARG);\n",
2748 g_free (the_type_lower);
2751 (no_gnu || for_cpp /* g++ has a cow with G_GNUC_UNUSED */)) {
2752 out_printf (out, "\t\tif (&ARG) break;\n");
2755 out_printf (out, "\t\tbreak;\n");
2757 out_printf (out, "\t}\n");
2761 add_property (Property *p, gboolean is_set)
2764 char *the_type_lower;
2770 line_no = p->set_line;
2773 line_no = p->get_line;
2778 name_upper = g_strdup (p->name);
2779 gob_strup (name_upper);
2780 the_type_lower = g_strdup (p->gtktype);
2781 gob_strdown (the_type_lower);
2783 out_printf (out, "\tcase PROP_%s:\n", name_upper);
2785 out_printf(out, "\t\t{\n");
2787 out_addline_infile (out, line_no);
2788 out_printf (out, "%s\n", cbuf);
2790 out_addline_outfile (out);
2791 out_printf (out, "\t\t}\n");
2793 g_free (name_upper);
2794 g_free (the_type_lower);
2796 out_printf (out, "\t\tbreak;\n");
2800 add_getset_arg(Class *c, gboolean is_set)
2803 const char *unused = "";
2804 const char *hack_unused = "";
2806 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
2807 unused = " G_GNUC_UNUSED";
2809 hack_unused = "if (&VAL || &pspec) break;\n\t\t";
2812 out_printf(out, "\nstatic void\n"
2813 "___object_%s_property (GObject *object,\n"
2814 "\tguint property_id,\n"
2815 "\t%sGValue *VAL%s,\n"
2816 "\tGParamSpec *pspec%s)\n"
2817 "#define __GOB_FUNCTION__ \"%s::%s_property\"\n"
2820 "\tself = %s (object);\n\n"
2821 "\tswitch (property_id) {\n",
2822 is_set ? "set" : "get",
2823 is_set ? "const " : "",
2827 is_set ? "set" : "get",
2832 for (li = c->nodes; li != NULL; li = li->next) {
2834 if (n->type == PROPERTY_NODE)
2835 add_property ((Property *)n, is_set);
2836 else if (n->type == ARGUMENT_NODE)
2837 add_argument ((Argument *)n, is_set);
2839 out_printf (out, "\tdefault:\n"
2840 "/* Apparently in g++ this is needed, glib is b0rk */\n"
2841 "#ifndef __PRETTY_FUNCTION__\n"
2842 "# undef G_STRLOC\n"
2843 "# define G_STRLOC __FILE__ \":\" G_STRINGIFY (__LINE__)\n"
2845 "\t\tG_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);\n"
2846 "\t\t%sbreak;\n\t}\n"
2848 "#undef __GOB_FUNCTION__\n", hack_unused);
2852 print_checks (Method *m, FuncArg *fa)
2856 gboolean checked_null = FALSE;
2857 is_void = (strcmp(m->mtype->name, "void")==0 &&
2858 m->mtype->pointer == NULL);
2860 for(li = fa->checks; li != NULL; li = li->next) {
2861 Check *ch = li->data;
2863 /* point to the method prot in .gob for failed checks */
2865 out_addline_infile(out, m->line_no);
2867 out_printf(out, "\tg_return_if_fail (");
2869 out_printf(out, "\tg_return_val_if_fail (");
2870 switch(ch->chtype) {
2872 out_printf(out, "%s != NULL", fa->name);
2873 checked_null = TRUE;
2876 s = make_pre_macro(fa->atype->name, "IS");
2878 out_printf(out, "%s (%s)", s, fa->name);
2880 /* if not check null, null may be valid */
2881 out_printf(out, "!(%s) || %s (%s)", fa->name,
2886 out_printf(out, "%s < %s", fa->name, ch->number);
2889 out_printf(out, "%s > %s", fa->name, ch->number);
2892 out_printf(out, "%s <= %s", fa->name, ch->number);
2895 out_printf(out, "%s >= %s", fa->name, ch->number);
2898 out_printf(out, "%s == %s", fa->name, ch->number);
2901 out_printf(out, "%s != %s", fa->name, ch->number);
2905 out_printf(out, ");\n");
2907 out_printf(out, ", (");
2908 print_type(out, m->mtype, TRUE);
2909 out_printf(out, ")%s);\n",
2910 m->onerror?m->onerror:"0");
2916 print_preconditions(Method *m)
2920 for(li=m->args;li;li=g_list_next(li)) {
2921 FuncArg *fa = li->data;
2923 print_checks(m, fa);
2926 out_addline_outfile(out);
2930 print_method_body (Method *m, gboolean pre, gboolean unused_self)
2932 out_printf(out, "{\n");
2934 out_addline_outfile(out);
2935 out_printf(out, "#define __GOB_FUNCTION__ \"%s::%s\"\n",
2936 ((Class *)class)->otype,
2939 print_preconditions(m);
2943 (no_gnu || for_cpp) &&
2945 ((FuncArg *)(m->args->data))->name != NULL &&
2946 strcmp (((FuncArg *)(m->args->data))->name, "self") == 0) {
2947 out_printf (out, "\tif (&self) { ; }\n");
2950 /* Note: the trailing }'s are on one line, this is so
2951 that we get the no return warning correctly and point to
2952 the correct line in the .gob file, yes this is slightly
2953 ugly in the .c file, but that is not supposed to be
2954 human readable anyway. */
2956 out_printf(out, "{\n");
2958 out_addline_infile(out, m->ccode_line);
2959 out_printf(out, "\t%s}", m->cbuf);
2962 /* Note, there is no \n between the last } and this } so that
2963 * errors/warnings reported on the end of the body get pointed to the
2964 * right line in the .gob source */
2965 out_printf(out, "}\n");
2968 out_addline_outfile(out);
2969 out_printf(out, "#undef __GOB_FUNCTION__\n");
2973 put_signal_args (Method *m)
2979 if (m->args->next == NULL)
2982 for (ali = m->gtktypes->next, li = m->args->next, i = 1;
2983 li != NULL && ali != NULL;
2984 li = li->next, ali = ali->next, i++) {
2985 FuncArg *fa = li->data;
2986 char *str = ali->data;
2987 char *cast = g_strdup (get_cast (str, FALSE));
2988 /* FIXME: This code is so fucking ugly it hurts */
2989 gboolean do_static =
2990 (strcmp (str, "STRING") == 0 ||
2991 strcmp (str, "BOXED") == 0 ||
2992 strncmp (str, "BOXED_", 6) == 0);
2997 cast = get_type (fa->atype, TRUE);
2999 /* we should have already proved before that
3000 the we know all the types */
3001 g_assert (cast != NULL);
3003 if (strncmp (str, "BOXED_", 6) == 0)
3004 t = g_strdup (&(str[6]));
3006 t = g_strconcat ("G_TYPE_", str, NULL);
3009 "\t___param_values[%d].g_type = 0;\n"
3010 "\tg_value_init (&___param_values[%d], %s);\n",
3014 if (strcmp (str, "UNICHAR") == 0)
3015 /* hack because glib is braindamaged */
3016 set_func = g_strdup ("g_value_set_uint");
3017 else if (strncmp (str, "BOXED_", 6) == 0)
3018 set_func = g_strdup ("g_value_set_static_boxed");
3020 set_func = g_strdup_printf ("g_value_set%s_%s",
3021 do_static ? "_static" : "",
3023 gob_strdown (set_func);
3025 out_printf (out, "\t%s (&___param_values[%d], (%s) %s);\n\n",
3026 set_func, i, cast, fa->name);
3034 clear_signal_args (Method *m)
3039 out_printf (out, "\n\tg_value_unset (&___param_values[0]);\n");
3041 if (m->args->next == NULL)
3044 for (li = m->args->next, i = 1;
3046 li = li->next, i++) {
3048 "\tg_value_unset (&___param_values[%d]);\n", i);
3053 get_arg_names_for_macro (Method *m)
3057 GString *gs = g_string_new(NULL);
3059 for(li=m->args;li;li=g_list_next(li)) {
3060 FuncArg *arg = li->data;
3061 g_string_sprintfa (gs, "%s___%s", sep, arg->name);
3064 return g_string_free (gs, FALSE);
3067 static gboolean method_is_void(Method *m)
3069 return !strcmp(m->mtype->name, "void") && !m->mtype->pointer;
3072 static const char *method_err_retval(Method *m)
3074 if (method_is_void(m))
3082 put_interface_parent_handler(Method *m)
3084 const char *errval = method_err_retval(m);
3085 char *name = replace_sep(m->interface, '_');
3086 char *args = get_arg_names_for_macro(m);
3088 out_printf(out, "#define PARENT_HANDLER(%s) (%s_parent_iface \\\n"
3089 "\t? %s_parent_iface->%s(%s) \\\n"
3090 "\t: %s)\n", args, name, name, m->id, args, errval);
3097 put_method(Method *m)
3099 char *s, *args, *doc;
3101 is_void = (strcmp(m->mtype->name, "void")==0 &&
3102 m->mtype->pointer == NULL);
3103 out_printf(out, "\n");
3104 if(m->method != OVERRIDE_METHOD) {
3105 doc = get_gtk_doc(m->id);
3107 out_printf(out, "%s", doc);
3113 case REGULAR_METHOD:
3115 out_addline_infile(out, m->line_no);
3116 if(m->scope == PRIVATE_SCOPE)
3117 print_method(out, "static ", "\n", "", " ", "", "\n",
3118 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3119 else /* PUBLIC, PROTECTED */
3120 print_method(out, "", "\n", "", " ", "", "\n",
3121 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3124 out_addline_outfile(out);
3125 put_interface_parent_handler(m);
3128 print_method_body(m, TRUE, TRUE);
3131 out_printf(out, "#undef PARENT_HANDLER\n");
3134 /* the outfile line was added above */
3136 case SIGNAL_FIRST_METHOD:
3137 case SIGNAL_LAST_METHOD:
3139 out_addline_infile(out, m->line_no);
3140 if(m->scope == PRIVATE_SCOPE)
3141 print_method(out, "static ", "\n", "", " ", "", "\n",
3142 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3143 else /* PUBLIC, PROTECTED */
3144 print_method(out, "", "\n", "", " ", "", "\n",
3145 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3146 out_printf (out, "{\n");
3148 out_addline_outfile (out);
3151 "\tGValue ___param_values[%d];\n"
3152 "\tGValue ___return_val;\n\n"
3153 "memset (&___return_val, 0, "
3154 "sizeof (___return_val));\n"
3155 "memset (&___param_values, 0, "
3156 "sizeof (___param_values));\n\n",
3157 g_list_length (m->args));
3159 print_preconditions (m);
3162 "\n\t___param_values[0].g_type = 0;\n"
3163 "\tg_value_init (&___param_values[0], G_TYPE_FROM_INSTANCE (%s));\n"
3164 "\tg_value_set_instance (&___param_values[0], (gpointer) %s);\n\n",
3165 ((FuncArg *)m->args->data)->name,
3166 ((FuncArg *)m->args->data)->name);
3168 put_signal_args (m);
3170 if (strcmp (m->gtktypes->data, "NONE") != 0) {
3171 const char *defret = NULL;
3173 out_printf (out, "\tg_value_init (&___return_val, G_TYPE_%s);\n",
3174 (char *)m->gtktypes->data);
3176 if (m->defreturn != NULL)
3177 defret = m->defreturn;
3178 else if (m->onerror != NULL)
3179 defret = m->onerror;
3181 if (defret != NULL) {
3183 /* FIXME: This code is so fucking ugly it hurts */
3184 gboolean do_static =
3185 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
3186 strcmp ((char *)m->gtktypes->data, "BOXED") == 0);
3187 char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
3189 cast = get_type (m->mtype, TRUE);
3191 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
3192 /* hack because glib is braindamaged */
3193 set_func = g_strdup ("g_value_set_uint");
3195 set_func = g_strdup_printf ("g_value_set%s_%s",
3196 do_static ? "_static" : "",
3197 (char *)m->gtktypes->data);
3198 gob_strdown (set_func);
3200 out_printf (out, "\t%s (&___return_val, (%s) (%s));\n",
3201 set_func, cast, defret);
3206 out_printf (out, "\n");
3209 s = g_strdup (m->id);
3212 out_printf(out, "\tg_signal_emitv (___param_values,\n"
3213 "\t\tobject_signals[%s_SIGNAL],\n"
3214 "\t\t0 /* detail */,\n"
3215 "\t\t&___return_val);\n", s);
3219 clear_signal_args (m);
3221 if (strcmp (m->gtktypes->data, "NONE") != 0) {
3222 char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
3224 /* Hack because glib is very very braindead */
3226 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
3227 strcmp ((char *)m->gtktypes->data, "BOXED") == 0 ||
3228 strcmp ((char *)m->gtktypes->data, "OBJECT") == 0 ||
3229 strcmp ((char *)m->gtktypes->data, "PARAM") == 0);
3231 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
3232 /* hack because glib is braindamaged */
3233 getfunc = g_strdup ("g_value_get_uint");
3235 getfunc = g_strdup_printf ("g_value_%s_%s",
3236 do_dup ? "dup" : "get",
3237 (char *)m->gtktypes->data);
3238 gob_strdown (getfunc);
3241 cast = get_type (m->mtype, TRUE);
3246 print_type (out, m->mtype, TRUE);
3248 " ___ret = (%s) %s (&___return_val);\n"
3249 "\t\tg_value_unset (&___return_val);\n"
3250 "\t\treturn ___ret;\n"
3257 out_printf(out, "}\n");
3262 out_addline_infile(out, m->line_no);
3263 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
3264 m, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE);
3265 print_method_body(m, FALSE, TRUE);
3266 /* the outfile line was added above */
3268 case VIRTUAL_METHOD:
3270 out_addline_infile(out, m->line_no);
3271 if(m->scope==PRIVATE_SCOPE)
3272 print_method(out, "static ", "\n", "", " ", "", "\n",
3273 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3274 else /* PUBLIC, PROTECTED */
3275 print_method(out, "", "\n", "", " ", "", "\n",
3276 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3277 out_printf(out, "{\n");
3278 out_addline_outfile(out);
3279 out_printf(out, "\t%sClass *klass;\n", typebase);
3280 print_preconditions(m);
3281 out_printf(out, "\tklass = %s_GET_CLASS(%s);\n\n"
3282 "\tif(klass->%s)\n",
3283 macrobase, ((FuncArg *)m->args->data)->name,
3285 if(strcmp(m->mtype->name, "void") == 0 &&
3286 m->mtype->pointer == NULL) {
3288 out_printf(out, "\t\t(*klass->%s)(%s",
3290 ((FuncArg *)m->args->data)->name);
3291 for(li=m->args->next;li;li=g_list_next(li)) {
3292 FuncArg *fa = li->data;
3293 out_printf(out, ",%s", fa->name);
3295 out_printf(out, ");\n}\n");
3298 out_printf(out, "\t\treturn (*klass->%s)(%s",
3300 ((FuncArg *)m->args->data)->name);
3301 for(li=m->args->next;li;li=g_list_next(li)) {
3302 FuncArg *fa = li->data;
3303 out_printf(out, ",%s", fa->name);
3305 out_printf(out, ");\n"
3308 print_type(out, m->mtype, TRUE);
3310 out_printf(out, ")(%s);\n}\n", m->defreturn);
3312 out_printf(out, ")(%s);\n}\n", m->onerror);
3314 out_printf(out, ")(0);\n}\n");
3320 out_addline_infile(out, m->line_no);
3321 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
3322 m, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE);
3323 print_method_body(m, FALSE, TRUE);
3324 /* the outfile line was added above */
3326 case OVERRIDE_METHOD:
3330 out_addline_infile(out, m->line_no);
3331 s = g_strdup_printf("\n___%x_", (guint)m->unique_id);
3332 print_method(out, "static ", s, "", " ", "", "\n",
3333 m, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE);
3335 out_addline_outfile(out);
3336 s = replace_sep(m->otype, '_');
3338 args = get_arg_names_for_macro(m);
3340 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
3341 "\t{ if(%s_CLASS(parent_class)->%s) \\\n"
3342 "\t\t(* %s_CLASS(parent_class)->%s)(%s); }\n",
3343 args, s, m->id, s, m->id, args);
3345 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
3346 "\t((%s_CLASS(parent_class)->%s)? \\\n"
3347 "\t\t(* %s_CLASS(parent_class)->%s)(%s): \\\n"
3349 args, s, m->id, s, m->id, args);
3350 out_printf(out, "(");
3351 print_type(out, m->mtype, TRUE);
3352 out_printf(out, ")%s))\n",
3353 m->onerror?m->onerror:"0");
3357 print_method_body(m, TRUE, TRUE);
3358 /* the outfile line was added above */
3359 out_printf(out, "#undef PARENT_HANDLER\n");
3361 case CONSTRUCTOR_METHOD:
3362 case DISPOSE_METHOD:
3363 case FINALIZE_METHOD:
3365 out_addline_infile(out, m->line_no);
3366 print_method(out, "static ", "\n", "", " ", "", "\n",
3367 m, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE);
3368 print_method_body(m, TRUE, TRUE);
3369 /* the outfile line was added above */
3378 char *outfile, *outfileh, *outfileph;
3380 outfilebase = g_strconcat (fullfilebase, for_cpp ? ".cc" : ".c", NULL);
3381 outfile = g_strconcat(outfilebase, no_touch ? "#gob#" : "", NULL);
3383 outfilehbase = g_strconcat (fullfilebase, ".h", NULL);
3384 outfileh = g_strconcat(outfilehbase, no_touch_headers ? "#gob#" : "", NULL);
3386 if ((privates > 0 || protecteds > 0 ||
3387 private_header == PRIVATE_HEADER_ALWAYS) &&
3388 private_header != PRIVATE_HEADER_NEVER) {
3389 char sep[2] = {0,0};
3392 outfilephbase = g_strconcat (fullfilebase, sep, "private.h", NULL);
3393 outfileph = g_strconcat (outfilephbase, no_touch ? "#gob#" : "", NULL);
3395 outfilephbase = NULL;
3401 out = fopen (outfile, "w");
3403 error_printf (GOB_ERROR, 0,
3404 "Cannot open outfile: %s", outfile);
3406 outh = fopen (outfileh, "w");
3408 error_printf (GOB_ERROR, 0,
3409 "Cannot open outfile: %s", outfileh);
3411 if (outfileph != NULL) {
3412 outph = fopen (outfileph, "w");
3413 if (outph == NULL) {
3414 error_printf (GOB_ERROR, 0,
3415 "Cannot open outfile: %s",
3423 put_argument_nongnu_wrappers (Class *c)
3427 if (get_properties < 0 && set_properties < 0)
3430 for (li = c->nodes; li != NULL; li = li->next) {
3432 const char *name, *gtktype;
3438 if (n->type == ARGUMENT_NODE) {
3439 Argument *a = (Argument *)n;
3441 gtktype = a->gtktype;
3443 get = a->get != NULL;
3444 set = a->set != NULL;
3445 } else if (n->type == PROPERTY_NODE) {
3446 Property *p = (Property *)n;
3448 gtktype = p->gtktype;
3450 get = p->get != NULL;
3451 set = p->set != NULL;
3456 aname = g_strdup (name);
3460 cast = get_type (atype, TRUE);
3462 cast = g_strdup (get_cast (gtktype, TRUE));
3466 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3467 "\"%s\",(%s)(arg)\n",
3468 macrobase, aname, name, cast);
3470 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3471 "\"%s\",(%s*)(arg)\n",
3472 macrobase, aname, name, cast);
3475 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3477 macrobase, aname, name);
3479 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3481 macrobase, aname, name);
3489 put_argument_gnu_wrappers(Class *c)
3493 if(get_properties < 0 && set_properties < 0)
3496 for (li = c->nodes; li != NULL; li = li->next) {
3498 const char *name, *gtktype;
3504 if (n->type == ARGUMENT_NODE) {
3505 Argument *a = (Argument *)n;
3507 gtktype = a->gtktype;
3509 get = a->get != NULL;
3510 set = a->set != NULL;
3511 } else if (n->type == PROPERTY_NODE) {
3512 Property *p = (Property *)n;
3514 gtktype = p->gtktype;
3516 get = p->get != NULL;
3517 set = p->set != NULL;
3522 aname = g_strdup (name);
3526 cast = get_type (atype, TRUE);
3528 cast = g_strdup (get_cast (gtktype, TRUE));
3532 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3533 "\"%s\", __extension__ ({%sz = (arg); z;})\n",
3534 macrobase, aname, name, cast);
3536 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3537 "\"%s\", __extension__ ({%s*z = (arg); z;})\n",
3538 macrobase, aname, name, cast);
3541 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3543 macrobase, aname, name);
3545 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3547 macrobase, aname, name);
3555 print_ccode_block(CCode *cc)
3558 switch(cc->cctype) {
3560 /* HT code is printed exactly like normal header
3561 code but is printed before */
3564 out_printf(fp, "\n");
3567 /* AT code is printed exactly like normal 'all'
3568 code but is printed before */
3571 out_printf(outph, "\n");
3572 out_printf(outph, "%s\n", cc->cbuf);
3573 out_addline_infile(outph, cc->line_no);
3574 out_addline_outfile(outph);
3576 out_printf(outh, "\n");
3577 out_printf(outh, "%s\n", cc->cbuf);
3579 out_printf(fp, "\n");
3580 out_addline_infile(fp, cc->line_no);
3586 out_printf(fp, "\n");
3587 out_addline_infile(fp, cc->line_no);
3594 out_printf(fp, "\n");
3595 out_addline_infile(fp, cc->line_no);
3598 out_printf(fp, "%s\n", cc->cbuf);
3599 if(cc->cctype == C_CCODE ||
3600 cc->cctype == AD_CCODE ||
3601 cc->cctype == A_CCODE ||
3602 cc->cctype == AT_CCODE ||
3603 cc->cctype == PH_CCODE)
3604 out_addline_outfile(fp);
3608 print_class_block(Class *c)
3612 gboolean printed_private = FALSE;
3616 out_printf(outph ? outph : outh, "#include <gtk/gtk.h>\n");
3617 out_printf(outph ? outph : outh, "#include <glade/glade-xml.h>\n\n");
3621 out_printf(out, "/* utility types we may need */\n");
3622 if(special_array[SPECIAL_2POINTER])
3623 out_printf(out, "typedef struct { "
3624 "gpointer a; gpointer b; "
3625 "} ___twopointertype;\n");
3626 if(special_array[SPECIAL_3POINTER])
3627 out_printf(out, "typedef struct { "
3628 "gpointer a; gpointer b; "
3630 "} ___threepointertype;\n");
3631 if(special_array[SPECIAL_INT_POINTER])
3632 out_printf(out, "typedef struct { "
3633 "gint a; gpointer b; "
3634 "} ___intpointertype;\n");
3635 out_printf(out, "\n");
3638 out_printf(outh, "\n/*\n"
3639 " * Type checking and casting macros\n"
3641 out_printf(outh, "#define %s\t"
3642 "(%s_get_type())\n",
3643 macrotype, funcbase);
3644 out_printf(outh, "#define %s(obj)\t"
3645 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s)\n",
3646 macrobase, funcbase, typebase);
3647 out_printf(outh, "#define %s_CONST(obj)\t"
3648 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s const)\n",
3649 macrobase, funcbase, typebase);
3650 out_printf(outh, "#define %s_CLASS(klass)\t"
3651 "G_TYPE_CHECK_CLASS_CAST((klass), %s_get_type(), %sClass)\n",
3652 macrobase, funcbase, typebase);
3653 out_printf(outh, "#define %s(obj)\t"
3654 "G_TYPE_CHECK_INSTANCE_TYPE((obj), %s_get_type ())\n\n",
3657 "#define %s_GET_CLASS(obj)\t"
3658 "G_TYPE_INSTANCE_GET_CLASS((obj), %s_get_type(), %sClass)\n",
3659 macrobase, funcbase, typebase);
3661 if ( ! no_self_alias) {
3662 out_printf(out, "/* self casting macros */\n");
3663 out_printf(out, "#define SELF(x) %s(x)\n", macrobase);
3664 out_printf(out, "#define SELF_CONST(x) %s_CONST(x)\n", macrobase);
3665 out_printf(out, "#define IS_SELF(x) %s(x)\n", macrois);
3666 out_printf(out, "#define TYPE_SELF %s\n", macrotype);
3667 out_printf(out, "#define SELF_CLASS(x) %s_CLASS(x)\n\n",
3669 out_printf(out, "#define SELF_GET_CLASS(x) %s_GET_CLASS(x)\n\n",
3672 out_printf(out, "/* self typedefs */\n");
3673 out_printf(out, "typedef %s Self;\n", typebase);
3674 out_printf(out, "typedef %sClass SelfClass;\n\n", typebase);
3678 always_private_struct) {
3679 out_printf (outh, "\n/* Private structure type */\n");
3680 out_printf (outh, "typedef struct _%sPrivate %sPrivate;\n",
3681 typebase, typebase);
3683 out_printf (outh, "/* There are no privates, this "
3684 "structure is thus never defined */\n");
3687 out_printf (outh, "\n/*\n"
3688 " * Main object structure\n"
3690 s = replace_sep (c->otype, '_');
3692 out_printf (outh, "#ifndef __TYPEDEF_%s__\n"
3693 "#define __TYPEDEF_%s__\n", s, s);
3695 out_printf (outh, "typedef struct _%s %s;\n"
3696 "#endif\n", typebase, typebase);
3697 out_printf (outh, "struct _%s {\n\t%s __parent__;\n",
3698 typebase, ptypebase);
3699 for (li = c->nodes; li; li=li->next) {
3700 static gboolean printed_public = FALSE;
3702 Variable *v = (Variable *)n;
3703 if(n->type == VARIABLE_NODE &&
3704 v->scope == PUBLIC_SCOPE) {
3705 if( ! printed_public) {
3706 out_printf(outh, "\t/*< public >*/\n");
3707 printed_public = TRUE;
3709 put_variable((Variable *)n, outh);
3712 /* put protecteds always AFTER publics */
3713 for (li = c->nodes; li != NULL; li = li->next) {
3715 Variable *v = (Variable *)n;
3716 if (n->type == VARIABLE_NODE &&
3717 v->scope == PROTECTED_SCOPE) {
3718 if ( ! printed_private) {
3719 out_printf (outh, "\t/*< private >*/\n");
3720 printed_private = TRUE;
3722 put_variable ((Variable *)n, outh);
3726 always_private_struct) {
3727 if ( ! printed_private)
3728 out_printf (outh, "\t/*< private >*/\n");
3729 out_printf (outh, "\t%sPrivate *_priv;\n", typebase);
3731 out_printf (outh, "};\n");
3736 /* if we are to stick this into the private
3737 header, if not stick it directly into the
3744 out_printf (outfp, "struct _%sPrivate {\n",
3748 for(li=c->nodes; li; li=li->next) {
3750 Variable *v = (Variable *)n;
3751 if(n->type == VARIABLE_NODE &&
3752 v->scope == PRIVATE_SCOPE) {
3753 out_addline_infile(outfp, v->line_no);
3754 put_variable(v, outfp);
3757 out_addline_outfile(outfp);
3759 out_printf(outfp, "};\n");
3762 out_printf(outh, "\n/*\n"
3763 " * Class definition\n"
3765 out_printf(outh, "typedef struct _%sClass %sClass;\n",
3766 typebase, typebase);
3768 "struct _%sClass {\n\t%sClass __parent__;\n",
3769 typebase, ptypebase);
3770 for(li = c->nodes; li != NULL; li = li->next) {
3772 if(n->type == METHOD_NODE)
3773 put_vs_method((Method *)n);
3775 /* If BonoboX type class put down the epv */
3776 if (c->bonobo_object_class != NULL) {
3778 "\t/* Bonobo object epv */\n"
3779 "\tPOA_%s__epv _epv;\n",
3780 c->bonobo_object_class);
3782 /* put class scope variables */
3783 for (li = c->nodes; li != NULL; li = li->next) {
3785 Variable *v = (Variable *)n;
3786 if (n->type == VARIABLE_NODE &&
3787 v->scope == CLASS_SCOPE)
3788 put_variable ((Variable *)n, outh);
3790 out_printf (outh, "};\n\n");
3792 out_printf (out, "/* here are local prototypes */\n");
3793 if (set_properties > 0) {
3794 out_printf (out, "static void ___object_set_property "
3795 "(GObject *object, guint property_id, "
3796 "const GValue *value, GParamSpec *pspec);\n");
3798 if (get_properties > 0) {
3799 out_printf (out, "static void ___object_get_property "
3800 "(GObject *object, guint property_id, "
3801 "GValue *value, GParamSpec *pspec);\n");
3804 out_printf (outh, "\n/*\n"
3805 " * Public methods\n"
3808 if (!overrode_get_type) {
3810 * For ordinary "static" types it should be safe to mark the
3811 * get_type implementation as const, since the get_type
3812 * function return really is constant at the call boundary
3813 * (even though there is an initial setup on the first call).
3814 * But for dynamic types, since the registration is explicitly
3815 * separated, we need to settle for "pure" as the results of
3816 * get_type differ before and after type registration.
3818 out_printf(outh, "GType\t%s_get_type\t(void) %s;\n", funcbase,
3819 c->dynamic ? "G_GNUC_PURE" : "G_GNUC_CONST");
3823 out_printf(outh, "void\t%s_register_type\t(GTypeModule *);\n",
3827 for(li = c->nodes; li != NULL; li = li->next) {
3829 if(n->type == METHOD_NODE) {
3830 put_pub_method((Method *)n);
3831 put_prot_method((Method *)n);
3832 put_priv_method_prot((Method *)n);
3836 /* this idea is less and less apealing to me */
3838 out_printf (outh, "\n/*\n"
3839 " * Signal connection wrapper macros\n"
3842 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3843 put_signal_macros (c, TRUE);
3844 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3845 put_signal_macros (c, FALSE);
3846 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n");
3848 put_signal_macros (c, FALSE);
3849 out_printf(outh, "\n");
3852 out_printf (out, "\n/*\n"
3853 " * Signal connection wrapper macro shortcuts\n"
3855 put_local_signal_macros (c);
3856 out_printf(outh, "\n");
3859 /* argument wrapping macros */
3860 if(get_properties > 0 || set_properties > 0) {
3861 out_printf(outh, "\n/*\n"
3862 " * Argument wrapping macros\n"
3865 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3866 put_argument_gnu_wrappers(c);
3867 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3868 put_argument_nongnu_wrappers(c);
3869 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n");
3871 put_argument_nongnu_wrappers(c);
3876 for(li = c->nodes; li != NULL; li = li->next) {
3878 if(n->type == METHOD_NODE)
3879 add_signal_prots((Method *)n);
3885 if(any_method_to_alias(c)) {
3886 out_printf (out, "/* Short form macros */\n");
3887 make_method_aliases (c);
3890 add_interface_inits (c);
3892 if (!overrode_get_type) {
3893 if (c->bonobo_object_class != NULL)
3894 add_bonobo_object_get_type();
3895 else if (c->dynamic)
3896 add_dynamic_get_type();
3901 out_printf (out, "/* a macro for creating a new object of our type */\n");
3903 "#define GET_NEW ((%s *)g_object_new(%s_get_type(), NULL))\n\n",
3904 typebase, funcbase);
3906 out_printf (out, "/* a function for creating a new object of our type */\n");
3907 out_printf (out, "#include <stdarg.h>\n");
3909 "static %s * GET_NEW_VARG (const char *first, ...)%s;\n"
3910 "static %s *\nGET_NEW_VARG (const char *first, ...)\n"
3911 "{\n\t%s *ret;\n\tva_list ap;\n"
3912 "\tva_start (ap, first);\n"
3913 "\tret = (%s *)g_object_new_valist (%s_get_type (), "
3916 "\treturn ret;\n}\n\n",
3918 no_gnu ? "" : " G_GNUC_UNUSED",
3919 typebase, typebase, typebase, funcbase);
3923 out_printf (out, "/* a function to connect glade callback */\n");
3924 out_printf (out,"static void\n"
3925 "___glade_xml_connect_foreach(const gchar *handler_name,\n"
3926 "GObject *object,\n"
3927 "const gchar *signal_name,\n"
3928 "const gchar *signal_data,\n"
3929 "GObject *connect_object,\n"
3931 "gpointer user_data)\n"
3933 "\tstatic GModule * allsymbols = NULL;\n"
3935 "\tif (!allsymbols) allsymbols = g_module_open(NULL, 0);\n"
3936 "\tif (allsymbols) {\n"
3937 "\t\tgchar * func_name = g_strdup_printf(\"%s_%%s\", handler_name);\n"
3938 "\t\tGCallback func;\n"
3940 "\t\tif (!g_module_symbol(allsymbols, func_name, (gpointer)&func)){\n"
3941 "\t\t\tif (!g_module_symbol(allsymbols, handler_name, (gpointer)&func)) {\n"
3942 "\t\t\t\tg_warning(\"could not find signal handler '%%s'.\", func_name);\n"
3943 "\t\t\t\tg_free(func_name);\n"
3948 "\t\t\tg_signal_connect_data(object, signal_name, func, user_data, NULL, G_CONNECT_AFTER | G_CONNECT_SWAPPED);\n"
3950 "\t\t\tg_signal_connect_data(object, signal_name, func, user_data, NULL, G_CONNECT_SWAPPED);\n"
3951 "\t\tg_free(func_name);\n"
3958 for (li = nodes; li != NULL; li = li->next) {
3959 Node *node = li->data;
3960 if (node->type == CCODE_NODE) {
3961 CCode *cc = (CCode *)node;
3962 if (cc->cctype == AD_CCODE)
3963 print_ccode_block (cc);
3967 if (need_constructor)
3968 add_constructor (c);
3978 if(set_properties > 0) {
3979 add_getset_arg(c, TRUE);
3982 if(get_properties > 0) {
3983 add_getset_arg(c, FALSE);
3986 for(li = c->nodes; li != NULL; li = li->next) {
3988 if(n->type == METHOD_NODE)
3989 put_method((Method *)n);
3992 add_bad_hack_to_avoid_unused_warnings(c);
3996 print_useful_macros(void)
3998 int major = 0, minor = 0, pl = 0;
4001 sscanf (VERSION, "%d.%d.%d", &major, &minor, &pl);
4002 out_printf (out, "#define GOB_VERSION_MAJOR %d\n", major);
4003 out_printf (out, "#define GOB_VERSION_MINOR %d\n", minor);
4004 out_printf (out, "#define GOB_VERSION_PATCHLEVEL %d\n\n", pl);
4006 /* Useful priv macro thingie */
4007 /* FIXME: this should be done the same way that priv is, as a var,
4009 out_printf (out, "#define selfp (self->_priv)\n\n");
4013 print_more_useful_macros (void)
4016 out_printf (out, "#define ___GOB_LIKELY(expr) (expr)\n");
4017 out_printf (out, "#define ___GOB_UNLIKELY(expr) (expr)\n");
4019 out_printf (out, "#ifdef G_LIKELY\n");
4020 out_printf (out, "#define ___GOB_LIKELY(expr) G_LIKELY(expr)\n");
4021 out_printf (out, "#define ___GOB_UNLIKELY(expr) G_UNLIKELY(expr)\n");
4022 out_printf (out, "#else /* ! G_LIKELY */\n");
4023 out_printf (out, "#define ___GOB_LIKELY(expr) (expr)\n");
4024 out_printf (out, "#define ___GOB_UNLIKELY(expr) (expr)\n");
4025 out_printf (out, "#endif /* G_LIKELY */\n");
4030 print_file_comments(void)
4032 out_printf(outh, "/* Generated by GOB (v%s)"
4033 " (do not edit directly) */\n\n", VERSION);
4035 out_printf(outph, "/* Generated by GOB (v%s)"
4036 " (do not edit directly) */\n\n", VERSION);
4037 out_printf(out, "/* Generated by GOB (v%s)"
4038 " (do not edit directly) */\n\n", VERSION);
4040 out_printf(out, "/* End world hunger, donate to the World Food Programme, http://www.wfp.org */\n\n");
4044 print_includes(void)
4046 gboolean found_header;
4049 /* We may need string.h for memset */
4050 if ( ! g_list_find_custom(include_files, "string.h", (GCompareFunc)strcmp)) {
4051 out_printf(out, "#include <string.h> /* memset() */\n\n");
4054 p = g_strconcat(filebase, ".h", NULL);
4055 found_header = TRUE;
4056 if( ! g_list_find_custom(include_files, p, (GCompareFunc)strcmp)) {
4057 out_printf(out, "#include \"%s.h\"\n\n", filebase);
4058 found_header = FALSE;
4062 /* if we are creating a private header see if it was included */
4064 char sep[2] = {0,0};
4067 p = g_strconcat(filebase, sep, "private.h", NULL);
4068 if( ! g_list_find_custom(include_files, p,
4069 (GCompareFunc)strcmp)) {
4070 out_printf(out, "#include \"%s%sprivate.h\"\n\n",
4074 error_printf(GOB_WARN, 0,
4075 "Implicit private header include "
4077 "\tsource file, while public "
4078 "header is at a custom location, "
4080 "\texplicitly include "
4081 "the private header below the "
4089 print_header_prefixes(void)
4093 p = replace_sep(((Class *)class)->otype, '_');
4095 out_printf(outh, "#ifndef __%s_H__\n#define __%s_H__\n\n", p, p);
4097 out_printf(outph, "#ifndef __%s_PRIVATE_H__\n"
4098 "#define __%s_PRIVATE_H__\n\n"
4099 "#include \"%s.h\"\n\n", p, p, filebase);
4102 if( ! no_extern_c) {
4103 out_printf(outh, "#ifdef __cplusplus\n"
4105 "#endif /* __cplusplus */\n\n");
4107 out_printf(outph, "#ifdef __cplusplus\n"
4109 "#endif /* __cplusplus */\n\n");
4114 print_header_postfixes(void)
4117 out_printf(outh, "\n#ifdef __cplusplus\n"
4119 "#endif /* __cplusplus */\n");
4120 out_printf(outh, "\n#endif\n");
4123 out_printf(outph, "\n#ifdef __cplusplus\n"
4125 "#endif /* __cplusplus */\n");
4126 out_printf(outph, "\n#endif\n");
4135 /* print the AT_CCODE and CT_CCODE blocks */
4136 for(li = nodes; li != NULL; li = li->next) {
4137 Node *node = li->data;
4138 if(node->type == CCODE_NODE) {
4139 CCode *cc = (CCode *)node;
4140 if (cc->cctype == AT_CCODE ||
4141 cc->cctype == CT_CCODE)
4142 print_ccode_block((CCode *)node);
4148 print_header_top(void)
4152 /* mandatory includes */
4153 out_printf (outh, "#include <glib.h>\n");
4154 out_printf (outh, "#include <glib-object.h>\n");
4156 /* print the HT_CCODE blocks */
4157 for (li = nodes; li != NULL; li = li->next) {
4158 Node *node = li->data;
4159 if (node->type == CCODE_NODE) {
4160 CCode *cc = (CCode *)node;
4161 if (cc->cctype == HT_CCODE)
4162 print_ccode_block ((CCode *)node);
4168 print_enum (EnumDef *enode)
4175 funcprefix = replace_sep (enode->etype, '_');
4176 gob_strdown (funcprefix);
4177 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
4179 type = remove_sep (enode->etype);
4181 out_printf (outh, "\ntypedef enum {\n");
4183 for (li = enode->values; li != NULL; li = li->next) {
4184 EnumValue *value = li->data;
4186 char *sname = gob_strdown (g_strdup (value->name));
4188 while ((p = strchr (sname, '_')) != NULL)
4191 out_printf (outh, "\t%s_%s", enode->prefix, value->name);
4192 if (value->value != NULL)
4193 out_printf (outh, " = %s", value->value);
4194 if (li->next != NULL)
4195 out_printf (outh, ",\n");
4197 out_printf (outh, "\n");
4199 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
4200 enode->prefix, value->name,
4201 enode->prefix, value->name,
4207 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
4209 out_printf (outh, "} %s;\n", type);
4211 str = make_pre_macro (enode->etype, "TYPE");
4212 out_printf (outh, "#define %s ", str);
4215 out_printf (outh, "%s_get_type()\n", funcprefix);
4216 out_printf (outh, "GType %s_get_type (void) G_GNUC_CONST;\n\n", funcprefix);
4219 "GType\n%s_get_type (void)\n"
4221 "\tstatic GType type = 0;\n"
4222 "\tif ___GOB_UNLIKELY(type == 0)\n"
4223 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
4226 funcprefix, type, funcprefix);
4228 g_free (funcprefix);
4233 print_flags (Flags *fnode)
4241 funcprefix = replace_sep (fnode->ftype, '_');
4242 gob_strdown (funcprefix);
4243 out_printf (out, "static const GFlagsValue _%s_values[] = {\n",
4245 type = remove_sep (fnode->ftype);
4247 out_printf (outh, "\ntypedef enum {\n");
4249 for (i = 0, li = fnode->values; li != NULL; i++, li = li->next) {
4250 const char *name = li->data;
4252 char *sname = gob_strdown (g_strdup (name));
4254 while ((p = strchr (sname, '_')) != NULL)
4257 out_printf (outh, "\t%s_%s = 1<<%d",
4258 fnode->prefix, name, i);
4259 if (li->next != NULL)
4260 out_printf (outh, ",\n");
4262 out_printf (outh, "\n");
4264 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
4265 fnode->prefix, name,
4266 fnode->prefix, name,
4272 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
4274 out_printf (outh, "} %s;\n", type);
4276 str = make_pre_macro (fnode->ftype, "TYPE");
4277 out_printf (outh, "#define %s ", str);
4280 out_printf (outh, "%s_get_type()\n", funcprefix);
4281 out_printf (outh, "GType %s_get_type (void) G_GNUC_CONST;\n\n", funcprefix);
4284 "GType\n%s_get_type (void)\n"
4286 "\tstatic GType type = 0;\n"
4287 "\tif ___GOB_UNLIKELY(type == 0)\n"
4288 "\t\ttype = g_flags_register_static (\"%s\", _%s_values);\n"
4291 funcprefix, type, funcprefix);
4293 g_free (funcprefix);
4298 print_error (Error *enode)
4305 funcprefix = replace_sep (enode->etype, '_');
4306 gob_strdown (funcprefix);
4307 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
4309 type = remove_sep (enode->etype);
4311 out_printf (outh, "\ntypedef enum {\n");
4313 for (li = enode->values; li != NULL; li = li->next) {
4314 const char *name = li->data;
4316 char *sname = gob_strdown (g_strdup (name));
4318 while ((p = strchr (sname, '_')) != NULL)
4321 out_printf (outh, "\t%s_%s", enode->prefix, name);
4322 if (li->next != NULL)
4323 out_printf (outh, ",\n");
4325 out_printf (outh, "\n");
4327 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
4328 enode->prefix, name,
4329 enode->prefix, name,
4335 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
4337 out_printf (outh, "} %s;\n", type);
4339 str = make_pre_macro (enode->etype, "TYPE");
4340 out_printf (outh, "#define %s ", str);
4343 out_printf (outh, "%s_get_type ()\n", funcprefix);
4344 out_printf (outh, "GType %s_get_type (void) G_GNUC_CONST;\n\n", funcprefix);
4347 "GType\n%s_get_type (void)\n"
4349 "\tstatic GType type = 0;\n"
4350 "\tif ___GOB_UNLIKELY(type == 0)\n"
4351 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
4354 funcprefix, type, funcprefix);
4356 out_printf (outh, "#define %s %s_quark ()\n", enode->prefix, funcprefix);
4357 out_printf (outh, "GQuark %s_quark (void);\n\n", funcprefix);
4359 str = replace_sep (enode->etype, '-');
4363 "GQuark\n%s_quark (void)\n"
4365 "\tstatic GQuark q = 0;\n"
4367 "\t\tq = g_quark_from_static_string (\"%s\");\n"
4374 g_free (funcprefix);
4379 generate_outfiles(void)
4383 print_file_comments();
4389 print_header_prefixes();
4391 print_useful_macros();
4395 print_more_useful_macros ();
4397 for (li = nodes; li != NULL; li = li->next) {
4398 Node *node = li->data;
4399 if (node->type == CCODE_NODE) {
4400 CCode *cc = (CCode *)node;
4401 if (cc->cctype != HT_CCODE &&
4402 cc->cctype != AT_CCODE &&
4403 cc->cctype != AD_CCODE)
4404 print_ccode_block ((CCode *)node);
4405 } else if (node->type == CLASS_NODE) {
4406 print_class_block ((Class *)node);
4407 } else if (node->type == ENUMDEF_NODE) {
4408 print_enum ((EnumDef *)node);
4409 } else if (node->type == FLAGS_NODE) {
4410 print_flags ((Flags *)node);
4411 } else if (node->type == ERROR_NODE) {
4412 print_error ((Error *)node);
4414 g_assert_not_reached();
4418 print_header_postfixes();
4424 fprintf(stderr, "Gob version %s\n\n", VERSION);
4425 fprintf(stderr, "gob [options] file.gob\n\n");
4426 fprintf(stderr, "Options:\n"
4427 "\t--help,-h,-? Display this help\n"
4428 "\t--version Display version\n"
4429 "\t--exit-on-warn,-w Exit with an error on warnings\n"
4430 "\t--no-exit-on-warn Don't exit on warnings [default]\n"
4431 "\t--for-cpp Create C++ files\n"
4432 "\t--no-extern-c Never print extern \"C\" into the "
4434 "\t--no-gnu Never use GNU extentions\n"
4435 "\t--no-touch Don't touch output files unless they "
4437 "\t changed (implies --no-touch-headers)\n"
4438 "\t--no-touch-headers Don't touch headers unless they "
4440 "\t--always-private-header Always create a private header "
4442 "\t even if it would be empty\n"
4443 "\t--ondemand-private-header Create private header only when "
4446 "\t--no-private-header Don't create a private header, "
4448 "\t structure and protected "
4449 "prototypes inside c file\n"
4450 "\t--always-private-struct Always create a private pointer "
4452 "\t the object structure\n"
4453 "\t--m4 Preprocess source with m4. "
4454 "Following args will\n"
4455 "\t be passed to m4\n"
4456 "\t--m4-dir Print directory that will be "
4459 "\t--no-write,-n Don't write output files, just "
4461 "\t--no-lines Don't print '#line' to output\n"
4462 "\t--no-self-alias Don't create self type and macro "
4464 "\t--no-kill-underscores Ignored for compatibility\n"
4465 "\t-o,--output-dir The directory where output "
4466 "should be placed\n"
4467 "\t--file-sep[=c] replace default \'-\' file "
4468 "name separator\n\n"
4469 "\t--gtk3 Use gtk+3\n"
4471 fprintf(stderr, "End world hunger, donate to the World Food Programme, http://www.wfp.org\n");
4475 parse_options(int argc, char *argv[])
4478 int got_file = FALSE;
4479 int no_opts = FALSE;
4480 int m4_opts = FALSE; /* if we are just passing on args to m4 */
4484 for(i = 1 ; i < argc; i++) {
4486 char *new_commandline;
4487 g_assert(m4_commandline!=NULL);
4489 /* check whether this one looks like the filename */
4490 if((!strcmp(argv[i],"-") || argv[i][0] != '-')
4492 const gchar *m4_flags=use_m4_clean?"":M4_FLAGS;
4496 /* insert flags before the filename */
4497 new_commandline=g_strconcat(m4_commandline,
4505 /* just an ordinary option */
4507 new_commandline=g_strconcat(m4_commandline,
4512 /* free old commandline */
4513 g_free(m4_commandline);
4514 m4_commandline=new_commandline;
4516 } else if(no_opts ||
4517 argv[i][0] != '-') {
4520 fprintf(stderr, "Specify only one file!\n");
4526 } else if(strcmp(argv[i], "--help")==0) {
4529 } else if(strcmp(argv[i], "--version")==0) {
4530 fprintf(stderr, "Gob version %s\n", VERSION);
4532 } else if(strcmp(argv[i], "--exit-on-warn")==0) {
4533 exit_on_warn = TRUE;
4534 } else if(strcmp(argv[i], "--no-exit-on-warn")==0) {
4535 exit_on_warn = FALSE;
4536 } else if(strcmp(argv[i], "--for-cpp")==0) {
4538 } else if(strcmp(argv[i], "--no-touch")==0) {
4540 no_touch_headers = TRUE;
4541 } else if(strcmp(argv[i], "--no-touch-headers")==0) {
4542 no_touch_headers = TRUE;
4543 } else if(strcmp(argv[i], "--ondemand-private-header")==0) {
4544 private_header = PRIVATE_HEADER_ONDEMAND;
4545 } else if(strcmp(argv[i], "--always-private-header")==0) {
4546 private_header = PRIVATE_HEADER_ALWAYS;
4547 } else if(strcmp(argv[i], "--no-private-header")==0) {
4548 private_header = PRIVATE_HEADER_NEVER;
4549 } else if(strcmp(argv[i], "--no-gnu")==0) {
4551 } else if(strcmp(argv[i], "--no-extern-c")==0) {
4553 } else if(strcmp(argv[i], "--no-write")==0) {
4555 } else if(strcmp(argv[i], "--no-lines")==0) {
4557 } else if(strcmp(argv[i], "--no-self-alias")==0) {
4558 no_self_alias = TRUE;
4559 } else if(strcmp(argv[i], "--no-kill-underscores")==0) {
4561 } else if(strcmp(argv[i], "--always-private-struct")==0) {
4562 always_private_struct = TRUE;
4563 } else if(strcmp(argv[i], "--m4-dir")==0) {
4564 printf("%s\n",M4_INCLUDE_DIR);
4566 } else if(strcmp(argv[i], "--m4")==0) {
4570 m4_commandline=g_strdup(M4_COMMANDLINE);
4571 } else if(strcmp(argv[i], "--m4-clean")==0) {
4575 m4_commandline=g_strdup(M4_COMMANDLINE);
4576 } else if (strcmp (argv[i], "-o") == 0 ||
4577 strcmp (argv[i], "--output-dir") == 0) {
4579 output_dir = g_strdup (argv[i+1]);
4584 } else if (strncmp (argv[i], "-o=", strlen ("-o=")) == 0 ||
4587 strlen ("--output-dir=")) == 0) {
4588 char *p = strchr (argv[i], '=');
4589 g_assert (p != NULL);
4590 output_dir = g_strdup (p+1);
4591 } else if (strncmp (argv[i], "--file-sep=",
4592 strlen ("--file-sep=")) == 0) {
4593 char *p = strchr (argv[i], '=');
4594 g_assert (p != NULL);
4596 } else if (strncmp (argv[i], "--file-sep",
4597 strlen ("--file-sep")) == 0) {
4599 file_sep = (argv[i+1])[0];
4604 } else if(strcmp(argv[i], "--gtk3")==0) {
4606 } else if(strcmp(argv[i], "--")==0) {
4607 /*further arguments are files*/
4609 } else if(strncmp(argv[i], "--", 2)==0) {
4610 /*unknown long option*/
4611 fprintf(stderr, "Unknown option '%s'!\n", argv[i]);
4615 /*by now we know we have a string starting with
4616 - which is a short option string*/
4618 for(p = argv[i] + 1; *p; p++) {
4632 "Unknown option '%c'!\n", *p);
4641 /* if we are using m4, and got no filename, append m4 flags now */
4642 if(!got_file && use_m4 && !use_m4_clean) {
4643 char *new_commandline;
4644 new_commandline=g_strconcat(m4_commandline,
4648 g_free(m4_commandline);
4649 m4_commandline=new_commandline;
4655 compare_and_move (const char *old_filename)
4657 char *new_filename = g_strconcat (old_filename, "#gob#", NULL);
4659 gboolean equal = FALSE;
4661 old_f = fopen (old_filename, "r");
4664 gboolean error = FALSE;
4666 new_f = fopen (new_filename, "r");
4675 new_n = fread (new_buf, 1, sizeof (new_buf), new_f);
4676 if (ferror (new_f)) {
4678 error_printf (GOB_ERROR, 0,
4679 "Can't read %s: %s",
4681 g_strerror (errno));
4685 old_n = fread (old_buf, 1, sizeof (old_buf), old_f);
4687 || feof (new_f) != feof (old_f)
4689 || memcmp (new_buf, old_buf, new_n) != 0)
4698 error_printf (GOB_ERROR, 0, "Can't open %s: %s",
4699 new_filename, g_strerror (errno));
4707 if (! equal && unlink (old_filename) != 0) {
4708 error_printf (GOB_ERROR, 0, "Can't remove %s: %s",
4709 old_filename, g_strerror (errno));
4715 if (unlink (new_filename) != 0)
4716 error_printf (GOB_ERROR, 0, "Can't remove %s: %s",
4717 new_filename, g_strerror (errno));
4719 if (rename (new_filename, old_filename) != 0)
4720 error_printf (GOB_ERROR, 0, "Can't rename %s to %s: %s",
4721 new_filename, old_filename,
4722 g_strerror (errno));
4726 g_free (new_filename);
4730 main(int argc, char *argv[])
4732 parse_options(argc, argv);
4735 yyin = popen(m4_commandline, "r");
4737 fprintf(stderr, "Error: can't open pipe from '%s'\n",
4741 } else if(filename) {
4742 yyin = fopen(filename, "r");
4744 fprintf(stderr, "Error: can't open file '%s'\n",
4753 /* This is where parsing is done */
4756 error_print (GOB_ERROR, 0, "Parsing errors, quitting");
4758 /* close input file */
4759 if(use_m4) pclose(yyin);
4764 error_print (GOB_ERROR, 0, "no class defined");
4767 exit_on_error = FALSE;
4769 signals = count_signals ((Class *)class);
4770 set_properties = count_set_properties ((Class *)class) +
4771 count_set_arguments ((Class *)class);
4772 get_properties = count_get_properties ((Class *)class) +
4773 count_get_arguments ((Class *)class);
4774 overrides = count_overrides ((Class *)class);
4775 privates = count_privates ((Class *)class);
4776 protecteds = count_protecteds ((Class *)class);
4777 unreftors = count_unreftors ((Class *)class);
4778 destructors = count_destructors ((Class *)class);
4779 initializers = count_initializers ((Class *)class);
4780 glade_widgets = count_glade_widgets ((Class *)class);
4781 overrode_get_type = find_get_type ((Class *)class);
4784 make_inits ((Class *)class);
4786 find_constructor ((Class *)class);
4787 if (user_constructor != NULL)
4788 need_constructor = TRUE;
4790 find_dispose ((Class *)class);
4791 if (unreftors > 0 ||
4792 dispose_handler != NULL ||
4793 user_dispose_method != NULL)
4794 need_dispose = TRUE;
4796 find_finalize ((Class *)class);
4797 if (destructors > 0 ||
4799 user_finalize_method != NULL) {
4800 need_finalize = TRUE;
4803 check_bad_symbols ((Class *)class);
4804 check_duplicate_symbols ((Class *)class);
4805 check_duplicate_overrides ((Class *)class);
4806 check_duplicate_signals_args ((Class *)class);
4807 check_public_new ((Class *)class);
4808 check_vararg ((Class *)class);
4809 check_firstarg ((Class *)class);
4810 check_nonvoidempty ((Class *)class);
4811 check_signal_args ((Class *)class);
4812 check_property_types ((Class *)class);
4813 check_argument_types ((Class *)class);
4814 check_func_arg_checks ((Class *)class);
4815 check_func_attrs ((Class *)class);
4816 check_for_class_destructors ((Class *)class);
4818 exit_on_error = TRUE;
4823 any_special = setup_special_array ((Class *)class, special_array);
4827 generate_outfiles ();
4838 compare_and_move (outfilebase);
4840 compare_and_move (outfilephbase);
4842 if (no_touch_headers)
4843 compare_and_move (outfilehbase);