2 * Copyright (C) 1999,2000 the Free Software Foundation.
3 * Copyright (C) 2000 Eazel, Inc.
4 * Copyright (C) 2001-2011 George (Jiri) Lebl
6 * Author: George (Jiri) Lebl
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
34 #include "treefuncs.h"
42 char *filename = NULL;
52 extern GList *include_files;
54 extern GHashTable *gtk_doc_hash;
58 static char *outfilebase;
59 static char *outfilehbase;
60 static char *outfilephbase;
61 static char *funcbase;
62 static char *pfuncbase;
63 static char *macrobase;
65 static char *pmacrois;
66 static char *macrotype;
67 static char *pmacrotype;
68 static char *typebase;
69 static char *ptypebase;
71 char *output_dir = NULL;
75 static int signals = 0; /* number of signals */
76 static int set_properties = 0; /* number of named (set) properties */
77 static int get_properties = 0; /* number of named (get) properties */
78 static int overrides = 0; /* number of override methods */
79 static int privates = 0; /* number of private data members */
80 static int protecteds = 0; /* number of protected methods */
81 static int unreftors = 0; /* number of variable unreffing destructors */
82 static int destructors = 0; /* number of variable non-unreffing destructors */
83 static int initializers = 0; /* number of variable initializers */
84 static int glade_widgets = 0; /* number of glade widgets */
85 static gboolean overrode_get_type = FALSE; /* provided your won _get_type */
87 static gboolean made_aliases = FALSE; /* if we made any shorthand aliases
88 and need the REALLY UGLY HACK to
91 /* the special variable types we need to define */
92 static gboolean special_array[SPECIAL_LAST] = {0};
93 static gboolean any_special = FALSE;
95 static gboolean need_constructor = FALSE;
96 static Method * user_constructor = NULL;
98 static gboolean need_dispose = FALSE;
99 static Method * dispose_handler = NULL;
100 static Method * user_dispose_method = NULL;
102 static gboolean need_finalize = FALSE;
103 static Method * finalize_handler = NULL;
104 static Method * user_finalize_method = NULL;
110 gboolean no_touch = FALSE;
111 gboolean no_touch_headers = FALSE;
112 gboolean for_cpp = FALSE;
113 gboolean no_gnu = FALSE;
114 gboolean exit_on_warn = FALSE;
115 gboolean exit_on_error = TRUE;
116 gboolean got_error = FALSE;
117 gint private_header = PRIVATE_HEADER_ONDEMAND;
118 gboolean no_extern_c = FALSE;
119 gboolean no_write = FALSE;
120 gboolean no_lines = FALSE;
121 gboolean no_self_alias = FALSE;
122 gboolean always_private_struct = FALSE;
123 gboolean gtk3_ok = FALSE;
129 gboolean use_m4 = FALSE; /* preprocess sources with m4 */
130 gboolean use_m4_clean = FALSE; /* preprocess sources with m4, no m4 flags */
131 char *m4_commandline = NULL;
132 #define M4_INCLUDE_DIR PKGDATADIR "/m4"
133 #define M4_BASE_FILENAME "gobm4.m4"
134 #define M4_FLAGS "-P -s -I" M4_INCLUDE_DIR " -DGOBM4_GOB_VERSION=" VERSION " " M4_BASE_FILENAME
135 #define M4_COMMANDLINE "m4"
137 int method_unique_id = 1;
142 filebase = replace_sep (((Class *)class)->otype, file_sep);
143 gob_strdown (filebase);
145 if (output_dir != NULL &&
146 output_dir[0] != '\0') {
147 fullfilebase = g_build_filename (output_dir, filebase, NULL);
149 fullfilebase = g_strdup (filebase);
152 funcbase = replace_sep (((Class *)class)->otype, '_');
153 gob_strdown (funcbase);
155 pfuncbase = replace_sep (((Class *)class)->ptype, '_');
156 gob_strdown (pfuncbase);
158 macrobase = replace_sep (((Class *)class)->otype, '_');
159 gob_strup (macrobase);
161 macrois = make_pre_macro (((Class *)class)->otype, "IS");
162 pmacrois = make_pre_macro (((Class *)class)->ptype, "IS");
164 macrotype = make_pre_macro (((Class *)class)->otype, "TYPE");
165 pmacrotype = make_pre_macro (((Class *)class)->ptype, "TYPE");
167 typebase = remove_sep (((Class *)class)->otype);
169 ptypebase = remove_sep (((Class *)class)->ptype);
173 get_gtk_doc (const char *id)
180 val = g_hash_table_lookup(gtk_doc_hash, id);
182 return g_strdup_printf("/**\n * %s_%s:\n%s **/\n",
184 val = g_hash_table_lookup(gtk_doc_hash, id);
186 return g_strdup_printf("/**\n * %s_%s:\n%s **/\n",
192 print_type(FILE *fp, const Type *t, gboolean postfix_to_stars)
196 s = get_type(t, postfix_to_stars);
197 out_printf(fp, "%s", s);
203 print_method (FILE *fp,
204 const char *typeprefix,
205 const char *nameprefix,
206 const char *subnameprefix,
207 const char *namepostfix,
208 const char *afterargs,
211 gboolean print_funcattrs,
212 gboolean one_arg_per_line,
213 gboolean no_funcbase,
214 gboolean kill_underscore,
215 gboolean first_unused,
221 out_printf(fp, "%s", typeprefix);
222 print_type(fp, m->mtype, TRUE);
227 out_printf(fp, "%s%s%s%s(",
228 nameprefix, subnameprefix, id, namepostfix);
230 out_printf(fp, "%s%s_%s%s%s(",
231 nameprefix, funcbase, subnameprefix, id,
235 for(li=m->args; li; li=g_list_next(li)) {
236 FuncArg *arg = li->data;
237 const char *unused = "";
240 ! for_cpp && /* g++ has a cow with this */
243 unused = " G_GNUC_UNUSED";
246 print_type(fp, arg->atype, FALSE);
248 out_printf (fp, "___fake___");
250 out_printf(fp, "%s%s%s,%s", arg->name,
251 arg->atype->postfix ?
252 arg->atype->postfix : "",
254 one_arg_per_line ? "\n\t\t\t\t\t" : " ");
256 out_printf(fp, "%s%s%s", arg->name,
257 arg->atype->postfix ?
258 arg->atype->postfix : "",
262 out_printf(fp, ",%s...",
263 one_arg_per_line ? "\n\t\t\t\t\t" : " ");
265 out_printf(fp, "void");
267 /* Slightly icky: sometimes we are called st m->funcattrs
268 hasn't been set, but if so it should be NULL since its been
270 if(print_funcattrs && m->funcattrs != NULL
271 && strlen(m->funcattrs) > 0) {
272 /* To keep the output neat, we trim off the trailing '\n'
273 from the end of funcattrs for a moment. */
274 size_t funcattrs_len = strlen(m->funcattrs);
275 gboolean funcattrs_chomped = FALSE;
276 if((m->funcattrs)[funcattrs_len - 1] == '\n') {
277 m->funcattrs[funcattrs_len - 1] = '\0';
278 funcattrs_chomped = TRUE;
280 out_printf(fp, "%s)\n%s%s", afterargs, m->funcattrs, postfix);
281 /* Put it back like it was (though it shouldn't matter). */
282 if (funcattrs_chomped) {
283 (m->funcattrs)[funcattrs_len - 1] = '\n';
287 out_printf(fp, "%s)%s", afterargs, postfix);
292 any_method_to_alias(Class *c)
296 for(li=c->nodes;li;li=g_list_next(li)) {
297 Node *node = li->data;
298 if(node->type == METHOD_NODE) {
299 Method *m = (Method *)node;
301 if(m->method == INIT_METHOD ||
302 m->method == CLASS_INIT_METHOD ||
303 m->method == CONSTRUCTOR_METHOD ||
304 m->method == DISPOSE_METHOD ||
305 m->method == FINALIZE_METHOD ||
306 m->method == OVERRIDE_METHOD)
317 make_method_aliases (Class *c)
321 for(li = c->nodes; li != NULL; li = li->next) {
322 Node *node = li->data;
323 if(node->type == METHOD_NODE) {
324 Method *m = (Method *)node;
326 if(m->method == INIT_METHOD ||
327 m->method == CLASS_INIT_METHOD ||
328 m->method == CONSTRUCTOR_METHOD ||
329 m->method == DISPOSE_METHOD ||
330 m->method == FINALIZE_METHOD ||
331 m->method == OVERRIDE_METHOD)
334 out_printf (out, "#define self_%s %s_%s\n",
343 add_bad_hack_to_avoid_unused_warnings(const Class *c)
347 /* if we haven't had any methods, just return */
352 out_printf(out, "\n\n#if (!defined __GNUC__) || (defined __GNUC__ && defined __STRICT_ANSI__)\n");
354 "/*REALLY BAD HACK\n"
355 " This is to avoid unused warnings if you don't call\n"
356 " some method. I need to find a better way to do\n"
357 " this, not needed in GCC since we use some gcc\n"
358 " extentions to make saner, faster code */\n"
360 "___%s_really_bad_hack_to_avoid_warnings(void)\n"
362 out_printf(out, "\t((void (*)(void))GET_NEW_VARG)();\n");
363 for(li=c->nodes;li;li=g_list_next(li)) {
364 Node *node = li->data;
365 if(node->type == METHOD_NODE) {
366 Method *m = (Method *)node;
368 if(m->method == INIT_METHOD ||
369 m->method == CLASS_INIT_METHOD ||
370 m->method == CONSTRUCTOR_METHOD ||
371 m->method == DISPOSE_METHOD ||
372 m->method == FINALIZE_METHOD ||
373 m->method == OVERRIDE_METHOD)
376 /* in C++ mode we don't alias new */
377 if(for_cpp && strcmp(m->id, "new")==0)
380 out_printf(out, "\t((void (*)(void))self_%s)();\n", m->id);
383 out_printf(out, "\t___%s_really_bad_hack_to_avoid_warnings();\n",
386 out_printf(out, "}\n#endif /* !__GNUC__ || (__GNUC__ && __STRICT_ANSI__) */\n\n");
388 out_printf(out, "}\n\n");
392 put_variable(const Variable *v, FILE *fp)
394 out_printf(fp, "\t");
395 print_type(fp, v->vtype, FALSE);
396 out_printf(fp, "%s%s;", v->id,
398 v->vtype->postfix:"");
399 if(v->scope == PROTECTED_SCOPE)
400 out_printf(fp, " /* protected */");
401 out_printf(fp, "\n");
405 put_vs_method(const Method *m)
407 if(m->method != SIGNAL_LAST_METHOD &&
408 m->method != SIGNAL_FIRST_METHOD &&
409 m->method != VIRTUAL_METHOD)
412 /* if a signal mark it as such */
413 if(m->method != VIRTUAL_METHOD)
414 print_method(outh, "\t/*signal*/", "(* ", "", ") ", "", ";\n",
415 m, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE);
417 print_method(outh, "\t", "(* ", "", ") ", "", ";\n",
418 m, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE);
423 put_pub_method(const Method *m)
425 if(m->scope != PUBLIC_SCOPE)
428 out_addline_infile(outh, m->line_no);
429 print_method(outh, "", "\t", "", "\t", "", ";\n", m,
430 TRUE, TRUE, FALSE, TRUE, FALSE, FALSE);
431 out_addline_outfile(outh);
435 put_signal_macro (const Method *m, gboolean gnu)
437 if(m->method != SIGNAL_LAST_METHOD &&
438 m->method != SIGNAL_FIRST_METHOD)
443 out_printf (outh, "#define %s_connect__%s(object,func,data)\t"
444 "g_signal_connect(%s(object),\"%s\","
445 "(GCallback)(func),(data))\n",
446 funcbase, m->id, macrobase, m->id);
449 out_printf (outh, "#define %s_connect_after__%s(object,func,data)\t"
450 "g_signal_connect_after(%s(object),\"%s\","
451 "(GCallback)(func),(data))\n",
452 funcbase, m->id, macrobase, m->id);
455 out_printf (outh, "#define %s_connect_data__%s"
456 "(object,func,data,destroy_data,flags)\t"
457 "g_signal_connect_data(%s(object),\"%s\","
458 "(GCallback)(func),(data),(destroy_data),(GConnectFlags)(flags))\n",
459 funcbase, m->id, macrobase, m->id);
462 out_printf (outh, "#define %s_connect__%s(object,func,data)\t"
464 "%s(__extension__ ({%s *___object = (object); ___object; })),"
466 "(GCallback) __extension__ ({",
467 funcbase, m->id, macrobase, typebase, m->id);
468 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
469 " = (func); ", m, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE);
470 out_printf (outh, "___%s; }), (data))\n", m->id);
473 out_printf (outh, "#define %s_connect_after__%s(object,func,data)\t"
474 "g_signal_connect_after("
475 "%s(__extension__ ({%s *___object = (object); ___object; })),"
477 "(GCallback) __extension__ ({",
478 funcbase, m->id, macrobase, typebase, m->id);
479 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
480 " = (func); ", m, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE);
481 out_printf (outh, "___%s; }), (data))\n", m->id);
484 out_printf (outh, "#define %s_connect_data__%s"
485 "(object,func,data,destroy_data,flags)\t"
486 "g_signal_connect_data("
487 "%s(__extension__ ({%s *___object = (object); ___object; })),"
489 "(GCallback) __extension__ ({",
490 funcbase, m->id, macrobase, typebase, m->id);
491 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
492 " = (func); ", m, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE);
493 out_printf (outh, "___%s; }), (data), (destroy_data), (GConnectFlags)(flags))\n", m->id);
498 put_signal_macros (const Class *c, gboolean gnu)
505 for (li = c->nodes; li != NULL; li = li->next) {
506 const Node *n = li->data;
507 if (n->type == METHOD_NODE)
508 put_signal_macro ((Method *)n, gnu);
513 put_local_signal_macro (const Method *m)
515 if(m->method != SIGNAL_LAST_METHOD &&
516 m->method != SIGNAL_FIRST_METHOD)
520 out_printf (out, "#define self_connect__%s(object,func,data)\t"
521 "%s_connect__%s((object),(func),(data))\n",
522 m->id, funcbase, m->id);
525 out_printf (out, "#define self_connect_after__%s(object,func,data)\t"
526 "%s_connect_after__%s((object),(func),(data))\n",
527 m->id, funcbase, m->id);
530 out_printf (out, "#define self_connect_data__%s(object,func,data,destroy_data,flags)\t"
531 "%s_connect_data__%s((object),(func),(data),(destroy_data),(flags))\n",
532 m->id, funcbase, m->id);
536 put_local_signal_macros (const Class *c)
543 for (li = c->nodes; li != NULL; li = li->next) {
544 const Node *n = li->data;
545 if (n->type == METHOD_NODE)
546 put_local_signal_macro ((Method *)n);
552 put_prot_method(const Method *m)
556 if(m->scope != PROTECTED_SCOPE)
559 f = outph ? outph : out;
561 out_addline_infile(f, m->line_no);
562 print_method(f, "", "\t", "", "\t", "", ";\n",
563 m, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE);
564 out_addline_outfile(f);
568 put_priv_method_prot(const Method *m)
570 if(m->method == SIGNAL_LAST_METHOD ||
571 m->method == SIGNAL_FIRST_METHOD ||
572 m->method == VIRTUAL_METHOD) {
575 "static ", "___real_", "", " ", "", ";\n",
576 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
578 /* no else, here, it might still have a private prototype, it's not
581 if((m->method == OVERRIDE_METHOD &&
584 char *s = g_strdup_printf("___%x_", (guint)m->unique_id);
586 out_addline_infile(out, m->line_no);
587 print_method(out, "static ", s, "", " ", "",
588 no_gnu?";\n":" G_GNUC_UNUSED;\n",
589 m, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE);
591 out_addline_outfile(out);
593 } else if(m->scope == PRIVATE_SCOPE ||
594 m->method == INIT_METHOD ||
595 m->method == CLASS_INIT_METHOD ||
596 m->method == CONSTRUCTOR_METHOD ||
597 m->method == DISPOSE_METHOD ||
598 m->method == FINALIZE_METHOD) {
600 out_addline_infile(out, m->line_no);
601 print_method(out, "static ", "", "", " ", "",
602 no_gnu?";\n":" G_GNUC_UNUSED;\n",
603 m, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE);
605 out_addline_outfile(out);
610 make_func_arg (const char *typename, gboolean is_class, const char *name)
617 tn = g_strconcat (typename, ":Class", NULL);
619 tn = g_strdup (typename);
621 type = node_new (TYPE_NODE,
625 node = node_new (FUNCARG_NODE,
626 "atype:steal", (Type *)type,
629 return g_list_prepend (NULL, node);
633 make_inits(Class *cl)
635 int got_class_init = FALSE;
636 int got_init = FALSE;
639 for(li=cl->nodes;li;li=g_list_next(li)) {
641 if(n->type == METHOD_NODE) {
642 Method *m = (Method *)n;
643 if(m->method == INIT_METHOD) {
645 error_print(GOB_ERROR, m->line_no, "init defined more then once");
647 } else if(m->method == CLASS_INIT_METHOD) {
649 error_print(GOB_ERROR, m->line_no, "class_init defined more then once");
650 got_class_init = TRUE;
654 if(!got_class_init) {
655 Type *type = (Type *)node_new (TYPE_NODE,
658 node = node_new (METHOD_NODE,
660 "method", CLASS_INIT_METHOD,
663 "args:steal", make_func_arg (cl->otype,
666 "unique_id", method_unique_id++,
668 cl->nodes = g_list_prepend(cl->nodes, node);
671 Type *type = (Type *)node_new (TYPE_NODE,
674 node = node_new (METHOD_NODE,
676 "method", INIT_METHOD,
679 "args:steal", make_func_arg (cl->otype,
680 FALSE /* is_class */,
682 "unique_id", method_unique_id++,
684 cl->nodes = g_list_prepend(cl->nodes, node);
689 find_method(const Class *cl, int method, const char *id)
693 for(li=cl->nodes;li;li=g_list_next(li)) {
695 if(n->type == METHOD_NODE) {
696 Method *m = (Method *)n;
697 if (m->method == method
698 && (id == NULL || strcmp(m->id, id)==0))
707 find_constructor(const Class *cl)
709 user_constructor = find_method(cl, CONSTRUCTOR_METHOD, NULL);
713 find_dispose(const Class *cl)
715 dispose_handler = find_method(cl, OVERRIDE_METHOD, "dispose");
716 if (dispose_handler != NULL) {
717 if(strcmp(dispose_handler->otype, "G:Object") != 0)
718 error_print(GOB_ERROR, dispose_handler->line_no,
719 "dispose method override "
720 "of class other then "
722 if(g_list_length(dispose_handler->args) != 1)
723 error_print(GOB_ERROR, dispose_handler->line_no,
724 "dispose method override "
725 "with more then one "
729 user_dispose_method = find_method(cl, DISPOSE_METHOD, NULL);
733 find_finalize(const Class *cl)
735 finalize_handler = find_method(cl, OVERRIDE_METHOD, "finalize");
736 if (finalize_handler != NULL) {
737 if(strcmp(finalize_handler->otype, "G:Object") != 0)
738 error_print(GOB_ERROR, finalize_handler->line_no,
739 "finalize method override "
740 "of class other then "
742 if(g_list_length(finalize_handler->args) != 1)
743 error_print(GOB_ERROR, finalize_handler->line_no,
744 "finalize method override "
745 "with more then one "
749 user_finalize_method = find_method(cl, FINALIZE_METHOD, NULL);
753 /* hash of method -> name of signal prototype */
754 static GHashTable *marsh = NULL;
756 /* list of methods with different signal prototypes,
757 we check this list if we can use a signal prototype of a
758 previous signal method, there are only uniques here */
759 static GList *eq_signal_methods = NULL;
761 /* compare a list of strings */
763 is_list_equal(const GList *a, const GList *b)
765 for(;a && b; a=a->next, b=b->next) {
766 if(strcmp(a->data, b->data)!=0) {
770 /* the the lists were different length */
777 find_same_type_signal(const Method *m)
780 for(li=eq_signal_methods;li;li=li->next) {
781 Method *mm = li->data;
782 if(is_list_equal(mm->gtktypes, m->gtktypes))
789 print_signal_marsal_args (const Method *m)
791 if (strcmp (m->gtktypes->next->data, "NONE") != 0) {
794 for (i = 0, li = m->gtktypes->next;
796 i++, li = li->next) {
799 if (strcmp (li->data, "UNICHAR") == 0)
800 /* hack because glib is braindamaged */
801 get_func = g_strdup ("g_value_get_uint");
802 else if (strncmp(li->data, "BOXED_", 6) == 0)
803 get_func = g_strdup ("g_value_get_boxed");
805 get_func = g_strdup_printf
806 ("g_value_get_%s", (char *)li->data);
808 gob_strdown (get_func);
809 out_printf (out, ",\n\t\t(%s) "
810 "%s (param_values + %d)",
811 get_cast (li->data, FALSE),
816 out_printf (out, ",\n\t\tdata2);\n");
821 add_signal_prots(Method *m)
827 gboolean ret_none = FALSE;
828 gboolean arglist_none = FALSE;
830 const char *unused = "";
832 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
833 unused = " G_GNUC_UNUSED";
836 if (m->method != SIGNAL_LAST_METHOD &&
837 m->method != SIGNAL_FIRST_METHOD)
841 marsh = g_hash_table_new(NULL, NULL);
843 g_assert (m->gtktypes->next != NULL);
845 ret_none = strcmp(m->gtktypes->data, "NONE") == 0;
846 arglist_none = strcmp(m->gtktypes->next->data, "NONE") == 0;
848 if (ret_none && arglist_none)
851 /* if we already did a signal prototype just use that */
852 mm = find_same_type_signal (m);
854 s = g_hash_table_lookup (marsh, mm);
855 g_hash_table_insert (marsh, m, s);
862 retcast = get_cast (m->gtktypes->data, FALSE);
864 s = g_strdup_printf("Sig%d", sig++);
866 g_hash_table_insert(marsh, m, s);
867 eq_signal_methods = g_list_prepend(eq_signal_methods, m);
869 /* we know that we'll know all the gtktypes (so get_cast can't fail) */
870 out_printf(out, "\ntypedef %s (*___%s) (%s *, ",
871 get_cast(m->gtktypes->data, FALSE), s, typebase);
873 if ( ! arglist_none) {
874 for (li = m->gtktypes->next; li != NULL; li = li->next)
875 out_printf (out, "%s, ", get_cast (li->data, FALSE));
877 out_printf (out, "gpointer);\n");
879 out_printf (out, "\nstatic void\n"
880 "___marshal_%s (GClosure *closure,\n"
881 "\tGValue *return_value%s,\n"
882 "\tguint n_param_values,\n"
883 "\tconst GValue *param_values,\n"
884 "\tgpointer invocation_hint%s,\n"
885 "\tgpointer marshal_data)\n"
892 out_printf (out, "\t%s v_return;\n", retcast);
894 out_printf (out, "\tregister ___%s callback;\n"
895 "\tregister GCClosure *cc = (GCClosure*) closure;\n"
896 "\tregister gpointer data1, data2;\n\n",
899 out_printf (out, "\tg_return_if_fail (n_param_values == %d);\n\n",
900 arglist_none ? 1 : g_list_length (m->gtktypes));
903 "\tif (G_CCLOSURE_SWAP_DATA (closure)) {\n"
904 "\t\tdata1 = closure->data;\n"
905 "\t\tdata2 = g_value_peek_pointer (param_values + 0);\n"
907 "\t\tdata1 = g_value_peek_pointer (param_values + 0);\n"
908 "\t\tdata2 = closure->data;\n"
911 out_printf (out, "\tcallback = (___%s) "
912 "(marshal_data != NULL ? marshal_data : cc->callback);"
916 out_printf (out, "\tcallback ((%s *)data1", typebase);
918 out_printf (out, "\tv_return = callback ((%s *)data1",
922 print_signal_marsal_args (m);
925 /* FIXME: This code is so fucking ugly it hurts */
926 gboolean take_ownership =
927 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
928 strcmp ((char *)m->gtktypes->data, "BOXED") == 0);
932 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
933 /* hack because glib is braindamaged */
934 set_func = g_strdup ("g_value_set_uint");
936 set_func = g_strdup_printf ("g_value_%s_%s",
939 (char *)m->gtktypes->data);
940 gob_strdown (set_func);
942 out_printf (out, "\n\t%s (return_value, v_return);\n",
947 if (no_gnu || for_cpp /* g++ has a cow with G_GNUC_UNUSED */) {
949 out_printf (out, "\n\treturn_value = NULL;\n");
950 out_printf (out, "\tinvocation_hint = NULL;\n");
953 out_printf (out, "}\n\n");
960 out_printf(out, "\n");
962 out_printf(out, "enum {\n");
963 for(li=c->nodes;li;li=g_list_next(li)) {
965 if(n->type == METHOD_NODE) {
966 Method *m = (Method *)n;
967 if(m->method == SIGNAL_LAST_METHOD ||
968 m->method == SIGNAL_FIRST_METHOD) {
969 char *s = g_strdup(m->id);
971 out_printf(out, "\t%s_SIGNAL,\n", s);
976 out_printf(out, "\tLAST_SIGNAL\n};\n\n");
978 if (set_properties > 0 ||
979 get_properties > 0) {
980 out_printf(out, "enum {\n\tPROP_0");
981 for(li=c->nodes;li;li=g_list_next(li)) {
983 if (n->type == PROPERTY_NODE) {
984 Property *p = (Property *)n;
985 char *s = g_strdup (p->name);
987 out_printf (out, ",\n\tPROP_%s", s);
989 } else if (n->type == ARGUMENT_NODE) {
990 Argument *a = (Argument *)n;
991 char *s = g_strdup(a->name);
993 out_printf(out, ",\n\tPROP_%s", s);
997 out_printf(out, "\n};\n\n");
1002 "static guint object_signals[LAST_SIGNAL] = {0};\n\n");
1004 out_printf(out, "/* pointer to the class of our parent */\n");
1005 out_printf(out, "static %sClass *parent_class = NULL;\n\n", ptypebase);
1009 add_interface_methods (Class *c, const char *interface)
1012 gboolean added_line = FALSE;
1014 for (li = c->nodes; li != NULL; li = li->next) {
1016 Method *m = (Method *)n;
1017 if (n->type != METHOD_NODE ||
1018 m->method == OVERRIDE_METHOD ||
1019 m->interface == NULL ||
1020 strcmp (m->interface, interface) != 0)
1023 if (m->line_no > 0) {
1024 out_addline_infile (out, m->line_no);
1026 } else if (m->line_no == 0 &&
1028 out_addline_outfile (out);
1031 out_printf (out, "\tiface->%s = self_%s;\n",
1035 out_addline_outfile (out);
1039 add_interface_inits (Class *c)
1043 if (c->interfaces == NULL)
1046 out_printf(out, "\n");
1048 for (li = c->interfaces; li != NULL; li = li->next) {
1049 const char *interface = li->data;
1051 char *name = replace_sep (interface, '_');
1052 char *type = remove_sep (interface);
1056 /* EEEK! evil, we should have some sort of option
1057 * to force this for arbitrary interfaces, since
1058 * some are Class and some are Iface. Glib is shite
1059 * in consistency. */
1061 if (strcmp (type, "GtkEditable") == 0 ||
1062 strcmp (type, "GTypePlugin") == 0)
1065 // We'll assume Iface is the standard ending
1070 /*GTK3 doesn't need Iface end*/
1074 out_printf (out, "\nstatic void\n"
1075 "___%s_init (%s%s *iface)\n"
1079 add_interface_methods (c, interface);
1081 out_printf (out, "}\n\n");
1089 add_interface_infos (void)
1092 for (li = ((Class *)class)->interfaces;
1095 char *name = replace_sep (li->data, '_');
1097 "\t\tstatic const GInterfaceInfo %s_info = {\n"
1098 "\t\t\t(GInterfaceInitFunc) ___%s_init,\n"
1108 add_interfaces (void)
1111 for (li = ((Class *)class)->interfaces;
1114 char *name = replace_sep (li->data, '_');
1115 char *type = make_pre_macro (li->data, "TYPE");
1118 "\t\tg_type_add_interface_static (type,\n"
1120 "\t\t\t&%s_info);\n",
1132 /*char *chunk_size = ((Class*)class)->chunk_size;*/
1136 "%s_get_type (void)\n"
1138 "\tstatic GType type = 0;\n\n"
1139 "\tif ___GOB_UNLIKELY(type == 0) {\n"
1140 "\t\tstatic const GTypeInfo info = {\n"
1141 "\t\t\tsizeof (%sClass),\n"
1142 "\t\t\t(GBaseInitFunc) NULL,\n"
1143 "\t\t\t(GBaseFinalizeFunc) NULL,\n"
1144 "\t\t\t(GClassInitFunc) %s_class_init,\n"
1145 "\t\t\t(GClassFinalizeFunc) NULL,\n"
1146 "\t\t\tNULL /* class_data */,\n"
1147 "\t\t\tsizeof (%s),\n"
1148 "\t\t\t%d /* n_preallocs */,\n"
1149 "\t\t\t(GInstanceInitFunc) %s_init,\n"
1152 funcbase, typebase, funcbase, typebase, prealloc, funcbase);
1154 add_interface_infos ();
1157 "\t\ttype = g_type_register_static (%s, \"%s\", &info, (GTypeFlags)%s);\n",
1158 pmacrotype, typebase, ((Class *)class)->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0");
1166 "\t\tgtk_type_set_chunk_alloc(type, %s);\n"
1168 chunk_size, chunk_size);
1178 add_bonobo_object_get_type (void)
1180 /* char *chunk_size = ((Class*)class)->chunk_size; */
1181 /* _vicious_ spanks seth with a rusty nail
1183 "\n#warning \"Bonobo isn't fully ported to glib 2.0 and "
1184 "gob2 doesn't officially support it yet. It'd be safer "
1185 "and a lot more fun to blow goats.\"\n");
1190 "%s_get_type (void)\n" /* 1 */
1192 "\tstatic GType type = 0;\n\n"
1193 "\tif ___GOB_UNLIKELY(type == 0) {\n"
1194 "\t\tstatic const GTypeInfo info = {\n"
1195 "\t\t\tsizeof (%sClass),\n" /* 2 */
1196 "\t\t\t(GBaseInitFunc) NULL,\n"
1197 "\t\t\t(GBaseFinalizeFunc) NULL,\n"
1198 "\t\t\t(GClassInitFunc) %s_class_init,\n" /* 3 */
1199 "\t\t\tNULL, /* class_finalize */\n"
1200 "\t\t\tNULL, /* class_data */\n"
1201 "\t\t\tsizeof (%s),\n" /* 4 */
1202 "\t\t\t0, /* n_preallocs */\n"
1203 "\t\t\t(GInstanceInitFunc) %s_init,\n" /* 5 */
1212 add_interface_infos ();
1215 "\t\ttype = bonobo_type_unique (\n"
1216 "\t\t\tBONOBO_OBJECT_TYPE,\n"
1217 "\t\t\tPOA_%s__init, NULL,\n" /* 1 */
1218 "\t\t\tG_STRUCT_OFFSET (%sClass, _epv),\n" /* 2 */
1219 "\t\t\t&info, \"%s\");\n", /* 3 */
1220 ((Class*)class)->bonobo_object_class /* 1 */,
1229 "\t\tgtk_type_set_chunk_alloc(type, %s);\n"
1231 chunk_size, chunk_size);
1240 add_overrides(Class *c, const char *oname,
1241 gboolean did_base_obj)
1247 done = g_hash_table_new (g_str_hash, g_str_equal);
1249 s = g_strdup ("GObject");
1250 g_hash_table_insert (done, s, s);
1252 for (li = c->nodes; li != NULL; li = li->next) {
1255 Method *m = (Method *)n;
1256 if(n->type != METHOD_NODE ||
1257 m->method != OVERRIDE_METHOD)
1260 s = remove_sep(m->otype);
1262 if(g_hash_table_lookup(done, s)) {
1266 g_hash_table_insert(done, s, s);
1268 f = replace_sep(m->otype, '_');
1271 out_printf(out, "\t%sClass *%s_class = (%sClass *)%s;\n",
1276 g_hash_table_foreach (done, (GHFunc)g_free, NULL);
1277 g_hash_table_destroy (done);
1281 make_run_signal_flags(Method *m, gboolean last)
1296 gs = g_string_new(NULL);
1299 g_string_assign(gs, "G_SIGNAL_RUN_LAST");
1301 g_string_assign(gs, "G_SIGNAL_RUN_FIRST");
1303 if(m->scope == PUBLIC_SCOPE)
1304 g_string_append(gs, " | G_SIGNAL_ACTION");
1306 for(li = m->flags; li; li = li->next) {
1307 char *flag = li->data;
1309 for(i=0;flags[i];i++) {
1310 if(strcmp(flags[i], flag)==0)
1313 /* if we haven't found it in our list */
1315 error_printf(GOB_WARN, m->line_no,
1316 "Unknown flag '%s' used, "
1317 "perhaps it was misspelled",
1320 g_string_sprintfa(gs, " | G_SIGNAL_%s", flag);
1324 char *ret = gs->str;
1325 g_string_free(gs, FALSE);
1332 add_signals(Class *c)
1336 out_printf(out, "\n");
1337 for(li=c->nodes;li;li=g_list_next(li)) {
1339 char *mar, *sig, *flags;
1340 gboolean is_none, last = FALSE;
1341 Method *m = (Method *)n;
1343 if(n->type != METHOD_NODE ||
1344 (m->method != SIGNAL_FIRST_METHOD &&
1345 m->method != SIGNAL_LAST_METHOD))
1348 if(m->method == SIGNAL_FIRST_METHOD)
1353 if(g_hash_table_lookup(marsh, m))
1354 mar = g_strconcat("___marshal_",
1355 (char *)g_hash_table_lookup(marsh, m),
1358 mar = g_strdup("g_cclosure_marshal_VOID__VOID");
1360 is_none = (strcmp(m->gtktypes->next->data, "NONE")==0);
1362 sig = g_strdup (m->id);
1364 flags = make_run_signal_flags (m, last);
1365 out_printf (out, "\tobject_signals[%s_SIGNAL] =\n"
1366 "\t\tg_signal_new (%s,\n"
1367 "\t\t\tG_TYPE_FROM_CLASS (g_object_class),\n"
1368 "\t\t\t(GSignalFlags)(%s),\n"
1369 "\t\t\tG_STRUCT_OFFSET (%sClass, %s),\n"
1370 "\t\t\tNULL, NULL,\n"
1372 "\t\t\tG_TYPE_%s, %d",
1373 sig, m->signal_name /*m->id* if not given signal_name*/,
1375 typebase, m->id, mar,
1376 (char *)m->gtktypes->data,
1377 is_none ? 0 : g_list_length(m->gtktypes->next));
1385 for(l = m->gtktypes->next; l != NULL; l = l->next) {
1386 char *str = l->data;
1387 if (strncmp (str, "BOXED_", 6) == 0)
1388 t = g_strdup (&(str[6]));
1390 t = g_strconcat ("G_TYPE_", str, NULL);
1391 out_printf (out, ",\n\t\t\t%s", t);
1396 out_printf(out, ");\n");
1398 if(strcmp(m->gtktypes->data, "NONE") != 0 ||
1401 out_printf(out, "\tif ___GOB_UNLIKELY(");
1402 if(strcmp(m->gtktypes->data, "NONE") != 0) {
1403 out_printf(out, "sizeof(");
1404 print_type(out, m->mtype, FALSE);
1405 out_printf(out, "%s",
1407 m->mtype->postfix : "");
1408 out_printf(out, ") != sizeof(%s) || ",
1409 get_cast(m->gtktypes->data, FALSE));
1412 for(al = m->args->next, gl = m->gtktypes->next;
1413 al != NULL && gl != NULL;
1414 al = al->next, gl = gl->next) {
1415 FuncArg *arg = al->data;
1416 char *gtkarg = gl->data;
1418 out_printf(out, "sizeof(");
1419 print_type(out, arg->atype, FALSE);
1420 out_printf(out, "%s",
1421 arg->atype->postfix ?
1422 arg->atype->postfix : "");
1423 out_printf(out, ") != sizeof(%s) || ",
1424 get_cast(gtkarg, FALSE));
1428 "parent_class == NULL /* avoid warning */");
1430 out_printf(out, ") {\n"
1431 "\t\tg_error(\"%s line %d: Type mismatch "
1432 "of \\\"%s\\\" signal signature\");\n"
1434 filename, m->line_no, m->id);
1441 set_def_handlers(Class *c, const char *oname)
1444 gboolean set_line = FALSE;
1446 out_printf(out, "\n");
1447 for(li = c->nodes; li; li = g_list_next(li)) {
1449 Method *m = (Method *)n;
1451 if(n->type != METHOD_NODE ||
1452 (m->method != SIGNAL_FIRST_METHOD &&
1453 m->method != SIGNAL_LAST_METHOD &&
1454 m->method != VIRTUAL_METHOD &&
1455 m->method != OVERRIDE_METHOD))
1458 if(m->line_no > 0 && m->cbuf) {
1459 out_addline_infile(out, m->line_no);
1461 } else if(set_line) {
1462 out_addline_outfile(out);
1467 if (m->method == OVERRIDE_METHOD) {
1469 s = replace_sep (m->otype, '_');
1473 dispose_handler != NULL &&
1474 strcmp (m->id, "dispose") == 0)
1475 out_printf (out, "\tg_object_class->dispose "
1477 else if (need_finalize &&
1479 strcmp(m->id, "finalize") == 0)
1481 "\tg_object_class->finalize = ___finalize;\n");
1482 else if (m->cbuf != NULL)
1484 "\t%s_class->%s = ___%x_%s_%s;\n",
1485 s, m->id, (guint)m->unique_id,
1488 out_printf(out, "\t%s_class->%s = NULL;\n",
1492 out_printf(out, "\t%s->%s = ___real_%s_%s;\n",
1496 out_printf(out, "\t%s->%s = NULL;\n",
1501 out_addline_outfile(out);
1505 make_argument (Argument *a)
1510 char *argflags[] = {
1518 flags = g_string_new ("(GParamFlags)(");
1520 if(a->get && a->set)
1521 g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
1523 g_string_append (flags, "G_PARAM_READABLE");
1525 g_string_append (flags, "G_PARAM_WRITABLE");
1527 g_assert(a->get || a->set);
1529 for (l = a->flags; l != NULL; l = l->next) {
1530 char *flag = l->data;
1532 if(strcmp (flag, "READABLE") == 0 ||
1533 strcmp (flag, "WRITABLE") == 0) {
1534 error_print(GOB_WARN, a->line_no,
1536 "WRITABLE argument flags are "
1537 "set automatically");
1540 for(i = 0; argflags[i]; i++) {
1541 if(strcmp(argflags[i], flag)==0)
1544 g_string_sprintfa(flags, " | %s%s", argflags[i] ? "G_PARAM_" : "", flag);
1547 g_string_append (flags, ")");
1549 s = g_strdup(a->name);
1551 if (!strcmp (a->gtktype, "ENUM"))
1552 out_printf(out, "\tparam_spec = g_param_spec_enum (\"%s\", NULL, NULL,\n"
1553 "\t\tG_TYPE_ENUM, 0,\n"
1555 a->name, flags->str);
1556 if (!strcmp (a->gtktype, "FLAGS"))
1557 out_printf(out, "\tparam_spec = g_param_spec_flags (\"%s\", NULL, NULL,\n"
1558 "\t\tG_TYPE_FLAGS, 0,\n"
1560 a->name, flags->str);
1561 else if (!strcmp (a->gtktype, "OBJECT"))
1562 out_printf(out, "\tparam_spec = g_param_spec_object (\"%s\", NULL, NULL,\n"
1563 "\t\tG_TYPE_OBJECT,\n"
1565 a->name, flags->str);
1566 else if (!strcmp (a->gtktype, "STRING"))
1567 out_printf(out, "\tparam_spec = g_param_spec_string (\"%s\", NULL, NULL,\n"
1570 a->name, flags->str);
1571 else if (!strcmp (a->gtktype, "INT"))
1572 out_printf(out, "\tparam_spec = g_param_spec_int (\"%s\", NULL, NULL,\n"
1573 "\t\tG_MININT, G_MAXINT,\n"
1576 a->name, flags->str);
1577 else if (!strcmp (a->gtktype, "UINT"))
1578 out_printf(out, "\tparam_spec = g_param_spec_uint (\"%s\", NULL, NULL,\n"
1579 "\t\t0, G_MAXUINT,\n"
1582 a->name, flags->str);
1583 else if (!strcmp (a->gtktype, "INT"))
1584 out_printf(out, "\tparam_spec = g_param_spec_int (\"%s\", NULL, NULL,\n"
1585 "\t\tG_MININT, G_MAXINT,\n"
1588 a->name, flags->str);
1589 else if (!strcmp (a->gtktype, "CHAR"))
1590 out_printf(out, "\tparam_spec = g_param_spec_char (\"%s\", NULL, NULL,\n"
1594 a->name, flags->str);
1595 else if (!strcmp (a->gtktype, "UCHAR"))
1596 out_printf(out, "\tparam_spec = g_param_spec_uchar (\"%s\", NULL, NULL,\n"
1600 a->name, flags->str);
1601 else if (!strcmp (a->gtktype, "BOOL") ||
1602 !strcmp (a->gtktype, "BOOLEAN"))
1603 out_printf(out, "\tparam_spec = g_param_spec_boolean (\"%s\", NULL, NULL,\n"
1606 a->name, flags->str);
1607 else if (!strcmp (a->gtktype, "LONG"))
1608 out_printf(out, "\tparam_spec = g_param_spec_long (\"%s\", NULL, NULL,\n"
1609 "\t\tG_MINLONG, G_MAXLONG,\n"
1612 a->name, flags->str);
1613 else if (!strcmp (a->gtktype, "ULONG"))
1614 out_printf(out, "\tparam_spec = g_param_spec_ulong (\"%s\", NULL, NULL,\n"
1615 "\t\t0, G_MAXULONG,\n"
1618 a->name, flags->str);
1619 else if (!strcmp (a->gtktype, "INT64"))
1620 out_printf(out, "\tparam_spec = g_param_spec_int64 (\"%s\", NULL, NULL,\n"
1621 "\t\tG_MININT64, G_MAXINT64,\n"
1624 a->name, flags->str);
1625 else if (!strcmp (a->gtktype, "UINT64"))
1626 out_printf(out, "\tparam_spec = g_param_spec_uint64 (\"%s\", NULL, NULL,\n"
1627 "\t\t0, G_MAXUINT64,\n"
1630 a->name, flags->str);
1631 else if (!strcmp (a->gtktype, "FLOAT"))
1632 out_printf(out, "\tparam_spec = g_param_spec_float (\"%s\", NULL, NULL,\n"
1633 "\t\t-G_MAXFLOAT, G_MAXFLOAT,\n"
1636 a->name, flags->str);
1637 else if (!strcmp (a->gtktype, "DOUBLE"))
1638 out_printf(out, "\tparam_spec = g_param_spec_double (\"%s\", NULL, NULL,\n"
1639 "\t\t-G_MAXDOUBLE, G_MAXDOUBLE,\n"
1642 a->name, flags->str);
1643 else if (!strcmp (a->gtktype, "POINTER"))
1644 out_printf(out, "\tparam_spec = g_param_spec_pointer (\"%s\", NULL, NULL,\n"
1646 a->name, flags->str);
1648 error_printf (GOB_ERROR, a->line_no,
1649 "%s type is not supported for arguments, try using properties",
1652 out_printf(out, "\tg_object_class_install_property (g_object_class,\n"
1653 "\t\tPROP_%s, param_spec);\n", s);
1657 g_string_free(flags, TRUE);
1660 #define value_for_print(str, alt) (str != NULL ? str : alt)
1663 make_property (Property *p)
1667 if (p->get == NULL && p->set == NULL) {
1668 error_print (GOB_ERROR, p->line_no,
1669 "Property has no getter nor setter");
1673 if (p->flags != NULL)
1674 error_print (GOB_WARN, p->line_no,
1675 "Overridden property, flags ignored");
1676 if (p->nick != NULL)
1677 error_print (GOB_WARN, p->line_no,
1678 "Overridden property, nick ignored");
1679 if (p->blurb != NULL)
1680 error_print (GOB_WARN, p->line_no,
1681 "Overridden property, blurb ignored");
1682 if (p->minimum != NULL)
1683 error_print (GOB_WARN, p->line_no,
1684 "Overridden property, minimum ignored");
1685 if (p->maximum != NULL)
1686 error_print (GOB_WARN, p->line_no,
1687 "Overridden property, maximum ignored");
1688 if (p->default_value != NULL)
1689 error_print (GOB_WARN, p->line_no,
1690 "Overridden property, default_value ignored");
1692 s = g_strdup (p->name);
1694 out_printf (out, "\tg_object_class_override_property (g_object_class,\n"
1696 "\t\t\"%s\");\n", s, value_for_print (p->canonical_name, p->name) );
1701 char *argflags[] = {
1709 flags = g_string_new ("(GParamFlags)(");
1711 if (p->get != NULL && p->set != NULL)
1712 g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
1713 else if (p->get != NULL)
1714 g_string_append (flags, "G_PARAM_READABLE");
1716 g_string_append (flags, "G_PARAM_WRITABLE");
1719 for (l = p->flags; l != NULL; l = l->next) {
1720 char *flag = l->data;
1722 if(strcmp (flag, "READABLE") == 0 ||
1723 strcmp (flag, "WRITABLE") == 0) {
1724 error_print(GOB_WARN, p->line_no,
1726 "WRITABLE argument flags are "
1727 "set automatically");
1730 for(i = 0; argflags[i]; i++) {
1731 if(strcmp(argflags[i], flag)==0)
1734 g_string_sprintfa(flags, " | %s%s", argflags[i] ? "G_PARAM_" : "", flag);
1737 g_string_append (flags, ")");
1739 if (strcmp (p->gtktype, "CHAR") == 0) {
1740 out_printf (out, "\tparam_spec = g_param_spec_char\n"
1741 "\t\t(\"%s\" /* name */,\n"
1742 "\t\t %s /* nick */,\n"
1743 "\t\t %s /* blurb */,\n"
1744 "\t\t %s /* minimum */,\n"
1745 "\t\t %s /* maximum */,\n"
1746 "\t\t %s /* default_value */,\n"
1748 value_for_print (p->canonical_name, p->name),
1749 value_for_print (p->nick, "NULL"),
1750 value_for_print (p->blurb, "NULL"),
1751 value_for_print (p->minimum, "-128"),
1752 value_for_print (p->maximum, "127"),
1753 value_for_print (p->default_value, "0"),
1755 } else if (strcmp (p->gtktype, "UCHAR") == 0) {
1756 out_printf (out, "\tparam_spec = g_param_spec_uchar\n"
1757 "\t\t(\"%s\" /* name */,\n"
1758 "\t\t %s /* nick */,\n"
1759 "\t\t %s /* blurb */,\n"
1760 "\t\t %s /* minimum */,\n"
1761 "\t\t %s /* maximum */,\n"
1762 "\t\t %s /* default_value */,\n"
1764 value_for_print (p->canonical_name, p->name),
1765 value_for_print (p->nick, "NULL"),
1766 value_for_print (p->blurb, "NULL"),
1767 value_for_print (p->minimum, "0"),
1768 value_for_print (p->maximum, "0xFF"),
1769 value_for_print (p->default_value, "0"),
1771 } else if (strcmp (p->gtktype, "BOOLEAN") == 0) {
1772 out_printf (out, "\tparam_spec = g_param_spec_boolean\n"
1773 "\t\t(\"%s\" /* name */,\n"
1774 "\t\t %s /* nick */,\n"
1775 "\t\t %s /* blurb */,\n"
1776 "\t\t %s /* default_value */,\n"
1778 value_for_print (p->canonical_name, p->name),
1779 value_for_print (p->nick, "NULL"),
1780 value_for_print (p->blurb, "NULL"),
1781 value_for_print (p->default_value, "FALSE"),
1783 } else if (strcmp (p->gtktype, "INT") == 0) {
1784 out_printf (out, "\tparam_spec = g_param_spec_int\n"
1785 "\t\t(\"%s\" /* name */,\n"
1786 "\t\t %s /* nick */,\n"
1787 "\t\t %s /* blurb */,\n"
1788 "\t\t %s /* minimum */,\n"
1789 "\t\t %s /* maximum */,\n"
1790 "\t\t %s /* default_value */,\n"
1792 value_for_print (p->canonical_name, p->name),
1793 value_for_print (p->nick, "NULL"),
1794 value_for_print (p->blurb, "NULL"),
1795 value_for_print (p->minimum, "G_MININT"),
1796 value_for_print (p->maximum, "G_MAXINT"),
1797 value_for_print (p->default_value, "0"),
1799 } else if (strcmp (p->gtktype, "UINT") == 0) {
1800 out_printf (out, "\tparam_spec = g_param_spec_uint\n"
1801 "\t\t(\"%s\" /* name */,\n"
1802 "\t\t %s /* nick */,\n"
1803 "\t\t %s /* blurb */,\n"
1804 "\t\t %s /* minimum */,\n"
1805 "\t\t %s /* maximum */,\n"
1806 "\t\t %s /* default_value */,\n"
1808 value_for_print (p->canonical_name, p->name),
1809 value_for_print (p->nick, "NULL"),
1810 value_for_print (p->blurb, "NULL"),
1811 value_for_print (p->minimum, "0"),
1812 value_for_print (p->maximum, "G_MAXUINT"),
1813 value_for_print (p->default_value, "0"),
1815 } else if (strcmp (p->gtktype, "LONG") == 0) {
1816 out_printf (out, "\tparam_spec = g_param_spec_long\n"
1817 "\t\t(\"%s\" /* name */,\n"
1818 "\t\t %s /* nick */,\n"
1819 "\t\t %s /* blurb */,\n"
1820 "\t\t %s /* minimum */,\n"
1821 "\t\t %s /* maximum */,\n"
1822 "\t\t %s /* default_value */,\n"
1824 value_for_print (p->canonical_name, p->name),
1825 value_for_print (p->nick, "NULL"),
1826 value_for_print (p->blurb, "NULL"),
1827 value_for_print (p->minimum, "G_MINLONG"),
1828 value_for_print (p->maximum, "G_MAXLONG"),
1829 value_for_print (p->default_value, "0"),
1831 } else if (strcmp (p->gtktype, "ULONG") == 0) {
1832 out_printf (out, "\tparam_spec = g_param_spec_ulong\n"
1833 "\t\t(\"%s\" /* name */,\n"
1834 "\t\t %s /* nick */,\n"
1835 "\t\t %s /* blurb */,\n"
1836 "\t\t %s /* minimum */,\n"
1837 "\t\t %s /* maximum */,\n"
1838 "\t\t %s /* default_value */,\n"
1840 value_for_print (p->canonical_name, p->name),
1841 value_for_print (p->nick, "NULL"),
1842 value_for_print (p->blurb, "NULL"),
1843 value_for_print (p->minimum, "0"),
1844 value_for_print (p->maximum, "G_MAXULONG"),
1845 value_for_print (p->default_value, "0"),
1847 } else if (strcmp (p->gtktype, "INT64") == 0) {
1848 out_printf (out, "\tparam_spec = g_param_spec_int64\n"
1849 "\t\t(\"%s\" /* name */,\n"
1850 "\t\t %s /* nick */,\n"
1851 "\t\t %s /* blurb */,\n"
1852 "\t\t %s /* minimum */,\n"
1853 "\t\t %s /* maximum */,\n"
1854 "\t\t %s /* default_value */,\n"
1856 value_for_print (p->canonical_name, p->name),
1857 value_for_print (p->nick, "NULL"),
1858 value_for_print (p->blurb, "NULL"),
1859 value_for_print (p->minimum, "G_MININT64"),
1860 value_for_print (p->maximum, "G_MAXINT64"),
1861 value_for_print (p->default_value, "0"),
1863 } else if (strcmp (p->gtktype, "UINT64") == 0) {
1864 out_printf (out, "\tparam_spec = g_param_spec_uint64\n"
1865 "\t\t(\"%s\" /* name */,\n"
1866 "\t\t %s /* nick */,\n"
1867 "\t\t %s /* blurb */,\n"
1868 "\t\t %s /* minimum */,\n"
1869 "\t\t %s /* maximum */,\n"
1870 "\t\t %s /* default_value */,\n"
1872 value_for_print (p->canonical_name, p->name),
1873 value_for_print (p->nick, "NULL"),
1874 value_for_print (p->blurb, "NULL"),
1875 value_for_print (p->minimum, "0"),
1876 value_for_print (p->maximum, "G_MAXUINT64"),
1877 value_for_print (p->default_value, "0"),
1879 } else if (strcmp (p->gtktype, "UNICHAR") == 0) {
1880 out_printf (out, "\tparam_spec = g_param_spec_unichar\n"
1881 "\t\t(\"%s\" /* name */,\n"
1882 "\t\t %s /* nick */,\n"
1883 "\t\t %s /* blurb */,\n"
1884 "\t\t %s /* default_value */,\n"
1886 value_for_print (p->canonical_name, p->name),
1887 value_for_print (p->nick, "NULL"),
1888 value_for_print (p->blurb, "NULL"),
1889 value_for_print (p->default_value, "0"),
1891 } else if (strcmp (p->gtktype, "ENUM") == 0) {
1892 char *type = make_me_type (p->extra_gtktype,
1894 out_printf (out, "\tparam_spec = g_param_spec_enum\n"
1895 "\t\t(\"%s\" /* name */,\n"
1896 "\t\t %s /* nick */,\n"
1897 "\t\t %s /* blurb */,\n"
1898 "\t\t %s /* enum_type */,\n"
1899 "\t\t %s /* default_value */,\n"
1901 value_for_print (p->canonical_name, p->name),
1902 value_for_print (p->nick, "NULL"),
1903 value_for_print (p->blurb, "NULL"),
1905 value_for_print (p->default_value, "0"),
1908 } else if (strcmp (p->gtktype, "FLAGS") == 0) {
1909 char *type = make_me_type (p->extra_gtktype,
1911 out_printf (out, "\tparam_spec = g_param_spec_flags\n"
1912 "\t\t(\"%s\" /* name */,\n"
1913 "\t\t %s /* nick */,\n"
1914 "\t\t %s /* blurb */,\n"
1915 "\t\t %s /* flags_type */,\n"
1916 "\t\t %s /* default_value */,\n"
1918 value_for_print (p->canonical_name, p->name),
1919 value_for_print (p->nick, "NULL"),
1920 value_for_print (p->blurb, "NULL"),
1922 value_for_print (p->default_value, "0"),
1925 } else if (strcmp (p->gtktype, "FLOAT") == 0) {
1926 out_printf (out, "\tparam_spec = g_param_spec_float\n"
1927 "\t\t(\"%s\" /* name */,\n"
1928 "\t\t %s /* nick */,\n"
1929 "\t\t %s /* blurb */,\n"
1930 "\t\t %s /* minimum */,\n"
1931 "\t\t %s /* maximum */,\n"
1932 "\t\t %s /* default_value */,\n"
1934 value_for_print (p->canonical_name, p->name),
1935 value_for_print (p->nick, "NULL"),
1936 value_for_print (p->blurb, "NULL"),
1937 value_for_print (p->minimum, "-G_MAXFLOAT"),
1938 value_for_print (p->maximum, "G_MAXFLOAT"),
1939 value_for_print (p->default_value, "0.0"),
1941 } else if (strcmp (p->gtktype, "DOUBLE") == 0) {
1942 out_printf (out, "\tparam_spec = g_param_spec_double\n"
1943 "\t\t(\"%s\" /* name */,\n"
1944 "\t\t %s /* nick */,\n"
1945 "\t\t %s /* blurb */,\n"
1946 "\t\t %s /* minimum */,\n"
1947 "\t\t %s /* maximum */,\n"
1948 "\t\t %s /* default_value */,\n"
1950 value_for_print (p->canonical_name, p->name),
1951 value_for_print (p->nick, "NULL"),
1952 value_for_print (p->blurb, "NULL"),
1953 value_for_print (p->minimum, "-G_MAXDOUBLE"),
1954 value_for_print (p->maximum, "G_MAXDOUBLE"),
1955 value_for_print (p->default_value, "0.0"),
1957 } else if (strcmp (p->gtktype, "STRING") == 0) {
1958 out_printf (out, "\tparam_spec = g_param_spec_string\n"
1959 "\t\t(\"%s\" /* name */,\n"
1960 "\t\t %s /* nick */,\n"
1961 "\t\t %s /* blurb */,\n"
1962 "\t\t %s /* default_value */,\n"
1964 value_for_print (p->canonical_name, p->name),
1965 value_for_print (p->nick, "NULL"),
1966 value_for_print (p->blurb, "NULL"),
1967 value_for_print (p->default_value, "NULL"),
1969 } else if (strcmp (p->gtktype, "PARAM") == 0) {
1970 char *type = make_me_type (p->extra_gtktype,
1972 out_printf (out, "\tparam_spec = g_param_spec_param\n"
1973 "\t\t(\"%s\" /* name */,\n"
1974 "\t\t %s /* nick */,\n"
1975 "\t\t %s /* blurb */,\n"
1976 "\t\t %s /* param_type */,\n"
1978 value_for_print (p->canonical_name, p->name),
1979 value_for_print (p->nick, "NULL"),
1980 value_for_print (p->blurb, "NULL"),
1984 } else if (strcmp (p->gtktype, "BOXED") == 0) {
1985 char *type = make_me_type (p->extra_gtktype,
1987 out_printf (out, "\tparam_spec = g_param_spec_boxed\n"
1988 "\t\t(\"%s\" /* name */,\n"
1989 "\t\t %s /* nick */,\n"
1990 "\t\t %s /* blurb */,\n"
1991 "\t\t %s /* boxed_type */,\n"
1993 value_for_print (p->canonical_name, p->name),
1994 value_for_print (p->nick, "NULL"),
1995 value_for_print (p->blurb, "NULL"),
1999 } else if (strcmp (p->gtktype, "POINTER") == 0) {
2000 out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
2001 "\t\t(\"%s\" /* name */,\n"
2002 "\t\t %s /* nick */,\n"
2003 "\t\t %s /* blurb */,\n"
2005 value_for_print (p->canonical_name, p->name),
2006 value_for_print (p->nick, "NULL"),
2007 value_for_print (p->blurb, "NULL"),
2009 /* FIXME: VALUE_ARRAY */
2010 } else if (strcmp (p->gtktype, "CLOSURE") == 0) {
2011 out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
2012 "\t\t(\"%s\" /* name */,\n"
2013 "\t\t %s /* nick */,\n"
2014 "\t\t %s /* blurb */,\n"
2016 value_for_print (p->canonical_name, p->name),
2017 value_for_print (p->nick, "NULL"),
2018 value_for_print (p->blurb, "NULL"),
2020 } else if (strcmp (p->gtktype, "OBJECT") == 0) {
2021 char *type = make_me_type (p->extra_gtktype,
2023 out_printf (out, "\tparam_spec = g_param_spec_object\n"
2024 "\t\t(\"%s\" /* name */,\n"
2025 "\t\t %s /* nick */,\n"
2026 "\t\t %s /* blurb */,\n"
2027 "\t\t %s /* object_type */,\n"
2029 value_for_print (p->canonical_name, p->name),
2030 value_for_print (p->nick, "NULL"),
2031 value_for_print (p->blurb, "NULL"),
2036 error_printf (GOB_ERROR, p->line_no,
2037 "%s type is not supported by properties",
2041 s = g_strdup (p->name);
2043 out_printf (out, "\tg_object_class_install_property (g_object_class,\n"
2045 "\t\tparam_spec);\n", s);
2048 g_string_free (flags, TRUE);
2053 make_arguments(Class *c)
2056 if (get_properties > 0)
2057 out_printf(out, "\tg_object_class->get_property = ___object_get_property;\n");
2058 if (set_properties > 0)
2059 out_printf(out, "\tg_object_class->set_property = ___object_set_property;\n");
2060 out_printf (out, " {\n");
2061 for (li = c->nodes; li != NULL; li = li->next) {
2063 if ((n->type == PROPERTY_NODE && ! ((Property *) n)->override)
2064 || n->type == ARGUMENT_NODE) {
2065 out_printf(out, "\tGParamSpec *param_spec;\n\n");
2070 for (li = c->nodes; li != NULL; li = li->next) {
2072 if (n->type == PROPERTY_NODE)
2073 make_property ((Property *)n);
2074 else if (n->type == ARGUMENT_NODE)
2075 make_argument ((Argument *)n);
2077 out_printf(out, " }\n");
2081 print_initializer(Method *m, Variable *v)
2088 if(v->initializer == NULL)
2091 if(v->scope == PRIVATE_SCOPE)
2092 root = g_strconcat(((FuncArg *)m->args->data)->name,
2095 root = g_strdup(((FuncArg *)m->args->data)->name);
2097 if(v->initializer_line > 0)
2098 out_addline_infile(out, v->initializer_line);
2100 if (v->initializer_simple)
2101 out_printf(out, "\t%s->%s = %s;\n",
2102 root, v->id, v->initializer);
2103 else if (strcmp(v->id, "_glade_xml") == 0)
2104 /* This is OK, this v->initializer string is set internally
2105 and it will eat exactly one string! */
2106 out_printf(out,v->initializer, ((FuncArg *)m->args->data)->name);
2108 out_printf(out, "%s", v->initializer);
2110 if(v->initializer_line > 0)
2111 out_addline_outfile(out);
2117 print_glade_widget(Method *m, Variable *v)
2122 if(!v->glade_widget)
2125 if(v->scope == PRIVATE_SCOPE)
2126 root = g_strconcat(((FuncArg *)m->args->data)->name,
2129 root = g_strdup(((FuncArg *)m->args->data)->name);
2131 cast = get_type(v->vtype, FALSE);
2132 out_printf(out, "\t%s->%s = (%s)glade_xml_get_widget(%s->_glade_xml, \"%s\");\n",
2133 root, v->id, cast, root, v->id);
2139 print_destructor (Variable *v)
2143 if(v->destructor == NULL)
2146 if(v->scope == PRIVATE_SCOPE)
2147 root = "self->_priv";
2151 if(v->destructor_simple) {
2152 if(v->destructor_line > 0)
2153 out_addline_infile(out, v->destructor_line);
2156 out_printf(out, "\tif(%s->%s) { "
2157 "(reinterpret_cast<void (*)(void *)>(%s)) ((gpointer)%s->%s); "
2158 "%s->%s = NULL; }\n",
2159 root, v->id, v->destructor, root, v->id,
2162 out_printf(out, "\tif(%s->%s) { "
2163 "%s ((gpointer) %s->%s); "
2164 "%s->%s = NULL; }\n",
2165 root, v->id, v->destructor, root, v->id,
2169 if(v->destructor_line > 0)
2170 out_addline_outfile(out);
2172 out_printf(out, "#define %s (%s->%s)\n", v->id, root, v->id);
2173 out_printf(out, "#define VAR %s\n", v->id);
2174 out_printf(out, "\t{\n");
2175 if(v->destructor_line > 0)
2176 out_addline_infile(out, v->destructor_line);
2178 out_printf(out, "\t%s}\n", v->destructor);
2180 if(v->destructor_line > 0)
2181 out_addline_outfile(out);
2182 out_printf(out, "\tmemset(&(%s), 0, sizeof(%s));\n",
2184 out_printf(out, "#undef VAR\n");
2185 out_printf(out, "#undef %s\n", v->id);
2190 add_constructor (Class *c)
2192 out_printf(out, "\nstatic GObject *\n"
2193 "___constructor (GType type, guint n_construct_properties, GObjectConstructParam *construct_properties)\n"
2196 "#define __GOB_FUNCTION__ \"%s::constructor\"\n",
2199 out_printf(out, "\tGObject *obj_self;\n");
2200 out_printf(out, "\t%s *self;\n", typebase);
2202 out_printf(out, "\tobj_self = G_OBJECT_CLASS (parent_class)->constructor (type, n_construct_properties, construct_properties);\n");
2203 out_printf(out, "\tself = %s (obj_self);\n", macrobase);
2205 if (user_constructor->line_no > 0)
2206 out_addline_infile (out, user_constructor->line_no);
2207 out_printf (out, "\t%s_constructor (self);\n", funcbase);
2208 if (user_constructor->line_no > 0)
2209 out_addline_outfile (out);
2211 out_printf(out, "\treturn obj_self;\n");
2212 out_printf(out, "}\n"
2213 "#undef __GOB_FUNCTION__\n\n");
2217 print_unreftors (Class *c)
2220 for(li = ((Class *)class)->nodes;
2224 Variable *v = (Variable *)n;
2225 if (n->type == VARIABLE_NODE &&
2226 v->scope != CLASS_SCOPE &&
2227 v->destructor_unref)
2228 print_destructor (v);
2233 add_dispose (Class *c)
2235 out_printf(out, "\nstatic void\n"
2236 "___dispose (GObject *obj_self)\n"
2239 "#define __GOB_FUNCTION__ \"%s::dispose\"\n",
2242 if (unreftors > 0 || user_dispose_method != NULL) {
2243 out_printf (out, "\t%s *self%s = %s (obj_self);\n",
2245 ! no_gnu ? " G_GNUC_UNUSED" : "",
2249 if (dispose_handler != NULL) {
2250 if (unreftors > 0) {
2251 print_unreftors (c);
2254 /* so we get possible bad argument warning */
2255 if (dispose_handler->line_no > 0)
2256 out_addline_infile (out, dispose_handler->line_no);
2257 out_printf (out, "\t___%x_%s_dispose(obj_self);\n",
2258 (guint)dispose_handler->unique_id, funcbase);
2259 if (dispose_handler->line_no > 0)
2260 out_addline_outfile (out);
2262 if (user_dispose_method != NULL) {
2263 if (user_dispose_method->line_no > 0)
2264 out_addline_infile (out, user_dispose_method->line_no);
2265 out_printf (out, "\t%s_dispose (self);\n", funcbase);
2266 if (user_dispose_method->line_no > 0)
2267 out_addline_outfile (out);
2270 if (unreftors > 0) {
2271 print_unreftors (c);
2275 "\tif (G_OBJECT_CLASS (parent_class)->dispose) \\\n"
2276 "\t\t(* G_OBJECT_CLASS (parent_class)->dispose) (obj_self);\n");
2279 out_printf(out, "}\n"
2280 "#undef __GOB_FUNCTION__\n\n");
2284 print_destructors (Class *c)
2287 for (li = ((Class *)class)->nodes;
2291 Variable *v = (Variable *)n;
2292 if (n->type == VARIABLE_NODE &&
2293 v->scope != CLASS_SCOPE &&
2294 ! v->destructor_unref)
2295 print_destructor (v);
2300 add_finalize (Class *c)
2304 "___finalize(GObject *obj_self)\n"
2307 "#define __GOB_FUNCTION__ \"%s::finalize\"\n",
2312 user_finalize_method != NULL) {
2313 const char *unused = "";
2315 unused = " G_GNUC_UNUSED";
2316 out_printf(out, "\t%s *self%s = %s (obj_self);\n",
2317 typebase, unused, macrobase);
2320 const char *unused = "";
2322 unused = " G_GNUC_UNUSED";
2323 out_printf(out, "\tgpointer priv%s = self->_priv;\n",
2327 if(finalize_handler) {
2328 if (destructors > 0) {
2329 print_destructors (c);
2332 /* so we get possible bad argument warning */
2333 if(finalize_handler->line_no > 0)
2334 out_addline_infile(out, finalize_handler->line_no);
2335 out_printf(out, "\t___%x_%s_finalize(obj_self);\n",
2336 (guint)finalize_handler->unique_id, funcbase);
2337 if(finalize_handler->line_no > 0)
2338 out_addline_outfile(out);
2340 if (user_finalize_method != NULL) {
2341 if (user_finalize_method->line_no > 0)
2342 out_addline_infile (out, user_finalize_method->line_no);
2343 out_printf (out, "\t%s_finalize (self);\n", funcbase);
2344 if (user_finalize_method->line_no > 0)
2345 out_addline_outfile (out);
2348 if (destructors > 0) {
2349 print_destructors (c);
2353 "\tif(G_OBJECT_CLASS(parent_class)->finalize) \\\n"
2354 "\t\t(* G_OBJECT_CLASS(parent_class)->finalize)(obj_self);\n");
2357 out_printf(out, "}\n"
2358 "#undef __GOB_FUNCTION__\n\n");
2362 make_bonobo_object_epv (Class *c, const char *classname)
2365 gboolean added_line = FALSE;
2367 for (li = c->nodes; li != NULL; li = li->next) {
2369 Method *m = (Method *)n;
2370 if(n->type != METHOD_NODE ||
2371 m->method == OVERRIDE_METHOD)
2374 if (m->bonobo_object_func) {
2375 if(m->line_no > 0) {
2376 out_addline_infile(out, m->line_no);
2378 } else if (m->line_no == 0 &&
2380 out_addline_outfile(out);
2383 out_printf (out, "\t%s->_epv.%s = self_%s;\n",
2384 classname, m->id, m->id);
2388 out_addline_outfile(out);
2394 const char *unused = "";
2398 unused = " G_GNUC_UNUSED";
2400 for(li=c->nodes;li;li=g_list_next(li)) {
2404 if(n->type != METHOD_NODE)
2407 if(m->method == INIT_METHOD) {
2409 out_addline_infile(out, m->line_no);
2410 print_method(out, "static ", "\n", "", " ", "", "\n",
2411 m, FALSE, FALSE, FALSE, TRUE, TRUE,
2413 out_printf(out, "{\n");
2415 out_addline_outfile(out);
2417 "#define __GOB_FUNCTION__ \"%s::init\"\n",
2420 out_printf(out, "\t%s->_priv = "
2421 "G_TYPE_INSTANCE_GET_PRIVATE(%s,%s,%sPrivate);\n",
2422 ((FuncArg *)m->args->data)->name,
2423 ((FuncArg *)m->args->data)->name,
2426 } else if(always_private_struct) {
2427 out_printf(out, "\t%s->_priv = NULL;\n",
2428 ((FuncArg *)m->args->data)->name);
2430 if(initializers > 0) {
2432 for(li = ((Class *)class)->nodes;
2436 Variable *v = (Variable *)n;
2437 if(n->type != VARIABLE_NODE ||
2438 v->scope == CLASS_SCOPE)
2440 print_initializer(m, v);
2443 if(glade_widgets > 0) {
2445 for(li = ((Class *)class)->nodes;
2449 Variable *v = (Variable *)n;
2450 if(n->type != VARIABLE_NODE ||
2451 v->scope == CLASS_SCOPE)
2453 print_glade_widget(m, v);
2456 } else if(m->method == CLASS_INIT_METHOD) {
2457 gboolean did_base_obj = FALSE;
2460 out_addline_infile(out, m->line_no);
2461 print_method(out, "static ", "\n", "", " ", "", "\n",
2462 m, FALSE, FALSE, FALSE, TRUE, TRUE,
2464 out_printf(out, "{\n");
2466 out_addline_outfile(out);
2468 "#define __GOB_FUNCTION__ \"%s::class_init\"\n",
2470 if (set_properties > 0 ||
2471 get_properties > 0 ||
2478 "g_object_class%s = "
2479 "(GObjectClass*) %s;\n",
2481 ((FuncArg *)m->args->data)->name);
2482 did_base_obj = TRUE;
2487 ((FuncArg *)m->args->data)->name,
2492 "\n\tg_type_class_add_private(%s,sizeof(%sPrivate));\n",
2493 ((FuncArg *)m->args->data)->name,
2496 if (initializers > 0) {
2498 for(li = ((Class *)class)->nodes;
2502 Variable *v = (Variable *)n;
2503 if(n->type == VARIABLE_NODE &&
2504 v->scope == CLASS_SCOPE)
2505 print_initializer(m, v);
2509 out_printf(out, "\n\tparent_class = ");
2511 out_printf(out, "(%sClass *)", ptypebase);
2512 out_printf(out, "g_type_class_ref (%s);\n",
2518 set_def_handlers(c, ((FuncArg *)m->args->data)->name);
2520 /* if there are no handlers for these things, we
2521 * need to set them up here */
2522 if(need_constructor)
2523 out_printf(out, "\tg_object_class->constructor "
2524 "= ___constructor;\n");
2525 if(need_dispose && !dispose_handler)
2526 out_printf(out, "\tg_object_class->dispose "
2528 if(need_finalize && !finalize_handler)
2529 out_printf(out, "\tg_object_class->finalize = "
2532 if(get_properties > 0 || set_properties > 0)
2535 if (c->bonobo_object_class != NULL) {
2536 make_bonobo_object_epv (c, ((FuncArg *)m->args->data)->name);
2542 out_printf(out, " {\n");
2543 out_addline_infile(out, m->ccode_line);
2544 out_printf(out, "%s\n", m->cbuf);
2545 out_addline_outfile(out);
2546 out_printf(out, " }\n");
2548 out_printf(out, "}\n"
2549 "#undef __GOB_FUNCTION__\n");
2554 add_argument (Argument *a, gboolean is_set)
2558 char *the_type_lower;
2563 line_no = a->set_line;
2566 line_no = a->get_line;
2570 s = g_strdup(a->name);
2572 out_printf(out, "\tcase PROP_%s:\n\t{", s);
2574 the_type_lower = g_strdup (a->gtktype);
2575 gob_strdown (the_type_lower);
2577 /* HACK because there is no g_value_set/get for unichar */
2578 if (strcmp (the_type_lower, "unichar") == 0) {
2579 g_free (the_type_lower);
2580 the_type_lower = g_strdup ("uint");
2585 const char *unused = "";
2587 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
2588 unused = " G_GNUC_UNUSED";
2591 if (a->atype != NULL &&
2592 /* gcc -Wbad-function-cast is wanking stupid, moronic
2593 and otherwise evil so we should just use a (gint)
2594 or (guint) cast, not the specific type cast */
2596 (strcmp (a->gtktype, "ENUM") != 0 &&
2597 strcmp (a->gtktype, "FLAGS") != 0)))
2598 cast = get_type (a->atype, TRUE);
2600 cast = g_strdup (get_cast (a->gtktype, FALSE));
2602 out_printf (out, "\t%s ARG%s = (%s) g_value_get_%s (VAL);\n",
2603 cast, unused, cast, the_type_lower);
2606 } else if ( ! is_set) {
2609 if (a->atype != NULL)
2610 cast = get_type (a->atype, TRUE);
2612 cast = g_strdup (get_cast (a->gtktype, FALSE));
2613 out_printf (out, "\t%s ARG;\n"
2614 "\tmemset (&ARG, 0, sizeof (%s));\n",
2620 out_printf(out, "\t\t{\n");
2622 out_addline_infile (out, line_no);
2623 out_printf (out, "%s\n", cbuf);
2625 out_addline_outfile (out);
2626 out_printf (out, "\t\t}\n");
2628 if (strcmp (a->gtktype, "OBJECT") == 0)
2629 out_printf (out, "\t\tg_value_set_%s (VAL, G_OBJECT (ARG));\n",
2632 out_printf (out, "\t\t"
2633 "g_value_set_%s (VAL, ARG);\n",
2636 g_free (the_type_lower);
2639 (no_gnu || for_cpp /* g++ has a cow with G_GNUC_UNUSED */)) {
2640 out_printf (out, "\t\tif (&ARG) break;\n");
2643 out_printf (out, "\t\tbreak;\n");
2645 out_printf (out, "\t}\n");
2649 add_property (Property *p, gboolean is_set)
2652 char *the_type_lower;
2658 line_no = p->set_line;
2661 line_no = p->get_line;
2666 name_upper = g_strdup (p->name);
2667 gob_strup (name_upper);
2668 the_type_lower = g_strdup (p->gtktype);
2669 gob_strdown (the_type_lower);
2671 out_printf (out, "\tcase PROP_%s:\n", name_upper);
2673 out_printf(out, "\t\t{\n");
2675 out_addline_infile (out, line_no);
2676 out_printf (out, "%s\n", cbuf);
2678 out_addline_outfile (out);
2679 out_printf (out, "\t\t}\n");
2681 g_free (name_upper);
2682 g_free (the_type_lower);
2684 out_printf (out, "\t\tbreak;\n");
2688 add_getset_arg(Class *c, gboolean is_set)
2691 const char *unused = "";
2692 const char *hack_unused = "";
2694 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
2695 unused = " G_GNUC_UNUSED";
2697 hack_unused = "if (&VAL || &pspec) break;\n\t\t";
2700 out_printf(out, "\nstatic void\n"
2701 "___object_%s_property (GObject *object,\n"
2702 "\tguint property_id,\n"
2703 "\t%sGValue *VAL%s,\n"
2704 "\tGParamSpec *pspec%s)\n"
2705 "#define __GOB_FUNCTION__ \"%s::%s_property\"\n"
2708 "\tself = %s (object);\n\n"
2709 "\tswitch (property_id) {\n",
2710 is_set ? "set" : "get",
2711 is_set ? "const " : "",
2715 is_set ? "set" : "get",
2720 for (li = c->nodes; li != NULL; li = li->next) {
2722 if (n->type == PROPERTY_NODE)
2723 add_property ((Property *)n, is_set);
2724 else if (n->type == ARGUMENT_NODE)
2725 add_argument ((Argument *)n, is_set);
2727 out_printf (out, "\tdefault:\n"
2728 "/* Apparently in g++ this is needed, glib is b0rk */\n"
2729 "#ifndef __PRETTY_FUNCTION__\n"
2730 "# undef G_STRLOC\n"
2731 "# define G_STRLOC __FILE__ \":\" G_STRINGIFY (__LINE__)\n"
2733 "\t\tG_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);\n"
2734 "\t\t%sbreak;\n\t}\n"
2736 "#undef __GOB_FUNCTION__\n", hack_unused);
2740 print_checks (Method *m, FuncArg *fa)
2744 gboolean checked_null = FALSE;
2745 is_void = (strcmp(m->mtype->name, "void")==0 &&
2746 m->mtype->pointer == NULL);
2748 for(li = fa->checks; li != NULL; li = li->next) {
2749 Check *ch = li->data;
2751 /* point to the method prot in .gob for failed checks */
2753 out_addline_infile(out, m->line_no);
2755 out_printf(out, "\tg_return_if_fail (");
2757 out_printf(out, "\tg_return_val_if_fail (");
2758 switch(ch->chtype) {
2760 out_printf(out, "%s != NULL", fa->name);
2761 checked_null = TRUE;
2764 s = make_pre_macro(fa->atype->name, "IS");
2766 out_printf(out, "%s (%s)", s, fa->name);
2768 /* if not check null, null may be valid */
2769 out_printf(out, "!(%s) || %s (%s)", fa->name,
2774 out_printf(out, "%s < %s", fa->name, ch->number);
2777 out_printf(out, "%s > %s", fa->name, ch->number);
2780 out_printf(out, "%s <= %s", fa->name, ch->number);
2783 out_printf(out, "%s >= %s", fa->name, ch->number);
2786 out_printf(out, "%s == %s", fa->name, ch->number);
2789 out_printf(out, "%s != %s", fa->name, ch->number);
2793 out_printf(out, ");\n");
2795 out_printf(out, ", (");
2796 print_type(out, m->mtype, TRUE);
2797 out_printf(out, ")%s);\n",
2798 m->onerror?m->onerror:"0");
2804 print_preconditions(Method *m)
2808 for(li=m->args;li;li=g_list_next(li)) {
2809 FuncArg *fa = li->data;
2811 print_checks(m, fa);
2814 out_addline_outfile(out);
2818 print_method_body (Method *m, gboolean pre, gboolean unused_self)
2820 out_printf(out, "{\n");
2822 out_addline_outfile(out);
2823 out_printf(out, "#define __GOB_FUNCTION__ \"%s::%s\"\n",
2824 ((Class *)class)->otype,
2827 print_preconditions(m);
2831 (no_gnu || for_cpp) &&
2833 ((FuncArg *)(m->args->data))->name != NULL &&
2834 strcmp (((FuncArg *)(m->args->data))->name, "self") == 0) {
2835 out_printf (out, "\tif (&self) { ; }\n");
2838 /* Note: the trailing }'s are on one line, this is so
2839 that we get the no return warning correctly and point to
2840 the correct line in the .gob file, yes this is slightly
2841 ugly in the .c file, but that is not supposed to be
2842 human readable anyway. */
2844 out_printf(out, "{\n");
2846 out_addline_infile(out, m->ccode_line);
2847 out_printf(out, "\t%s}", m->cbuf);
2850 /* Note, there is no \n between the last } and this } so that
2851 * errors/warnings reported on the end of the body get pointed to the
2852 * right line in the .gob source */
2853 out_printf(out, "}\n");
2856 out_addline_outfile(out);
2857 out_printf(out, "#undef __GOB_FUNCTION__\n");
2861 put_signal_args (Method *m)
2867 if (m->args->next == NULL)
2870 for (ali = m->gtktypes->next, li = m->args->next, i = 1;
2871 li != NULL && ali != NULL;
2872 li = li->next, ali = ali->next, i++) {
2873 FuncArg *fa = li->data;
2874 char *str = ali->data;
2875 char *cast = g_strdup (get_cast (str, FALSE));
2876 /* FIXME: This code is so fucking ugly it hurts */
2877 gboolean do_static =
2878 (strcmp (str, "STRING") == 0 ||
2879 strcmp (str, "BOXED") == 0 ||
2880 strncmp (str, "BOXED_", 6) == 0);
2885 cast = get_type (fa->atype, TRUE);
2887 /* we should have already proved before that
2888 the we know all the types */
2889 g_assert (cast != NULL);
2891 if (strncmp (str, "BOXED_", 6) == 0)
2892 t = g_strdup (&(str[6]));
2894 t = g_strconcat ("G_TYPE_", str, NULL);
2897 "\t___param_values[%d].g_type = 0;\n"
2898 "\tg_value_init (&___param_values[%d], %s);\n",
2902 if (strcmp (str, "UNICHAR") == 0)
2903 /* hack because glib is braindamaged */
2904 set_func = g_strdup ("g_value_set_uint");
2905 else if (strncmp (str, "BOXED_", 6) == 0)
2906 set_func = g_strdup ("g_value_set_static_boxed");
2908 set_func = g_strdup_printf ("g_value_set%s_%s",
2909 do_static ? "_static" : "",
2911 gob_strdown (set_func);
2913 out_printf (out, "\t%s (&___param_values[%d], (%s) %s);\n\n",
2914 set_func, i, cast, fa->name);
2922 clear_signal_args (Method *m)
2927 out_printf (out, "\n\tg_value_unset (&___param_values[0]);\n");
2929 if (m->args->next == NULL)
2932 for (li = m->args->next, i = 1;
2934 li = li->next, i++) {
2936 "\tg_value_unset (&___param_values[%d]);\n", i);
2941 get_arg_names_for_macro (Method *m)
2945 GString *gs = g_string_new(NULL);
2947 for(li=m->args;li;li=g_list_next(li)) {
2948 FuncArg *arg = li->data;
2949 g_string_sprintfa (gs, "%s___%s", sep, arg->name);
2952 return g_string_free (gs, FALSE);
2956 put_method(Method *m)
2958 char *s, *args, *doc;
2960 is_void = (strcmp(m->mtype->name, "void")==0 &&
2961 m->mtype->pointer == NULL);
2962 out_printf(out, "\n");
2963 if(m->method != OVERRIDE_METHOD) {
2964 doc = get_gtk_doc(m->id);
2966 out_printf(out, "%s", doc);
2971 case REGULAR_METHOD:
2973 out_addline_infile(out, m->line_no);
2974 if(m->scope == PRIVATE_SCOPE)
2975 print_method(out, "static ", "\n", "", " ", "", "\n",
2976 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
2977 else /* PUBLIC, PROTECTED */
2978 print_method(out, "", "\n", "", " ", "", "\n",
2979 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
2980 print_method_body(m, TRUE, TRUE);
2981 /* the outfile line was added above */
2983 case SIGNAL_FIRST_METHOD:
2984 case SIGNAL_LAST_METHOD:
2986 out_addline_infile(out, m->line_no);
2987 if(m->scope == PRIVATE_SCOPE)
2988 print_method(out, "static ", "\n", "", " ", "", "\n",
2989 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
2990 else /* PUBLIC, PROTECTED */
2991 print_method(out, "", "\n", "", " ", "", "\n",
2992 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
2993 out_printf (out, "{\n");
2995 out_addline_outfile (out);
2998 "\tGValue ___param_values[%d];\n"
2999 "\tGValue ___return_val;\n\n"
3000 "memset (&___return_val, 0, "
3001 "sizeof (___return_val));\n"
3002 "memset (&___param_values, 0, "
3003 "sizeof (___param_values));\n\n",
3004 g_list_length (m->args));
3006 print_preconditions (m);
3009 "\n\t___param_values[0].g_type = 0;\n"
3010 "\tg_value_init (&___param_values[0], G_TYPE_FROM_INSTANCE (%s));\n"
3011 "\tg_value_set_instance (&___param_values[0], (gpointer) %s);\n\n",
3012 ((FuncArg *)m->args->data)->name,
3013 ((FuncArg *)m->args->data)->name);
3015 put_signal_args (m);
3017 if (strcmp (m->gtktypes->data, "NONE") != 0) {
3018 const char *defret = NULL;
3020 out_printf (out, "\tg_value_init (&___return_val, G_TYPE_%s);\n",
3021 (char *)m->gtktypes->data);
3023 if (m->defreturn != NULL)
3024 defret = m->defreturn;
3025 else if (m->onerror != NULL)
3026 defret = m->onerror;
3028 if (defret != NULL) {
3030 /* FIXME: This code is so fucking ugly it hurts */
3031 gboolean do_static =
3032 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
3033 strcmp ((char *)m->gtktypes->data, "BOXED") == 0);
3034 char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
3036 cast = get_type (m->mtype, TRUE);
3038 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
3039 /* hack because glib is braindamaged */
3040 set_func = g_strdup ("g_value_set_uint");
3042 set_func = g_strdup_printf ("g_value_set%s_%s",
3043 do_static ? "_static" : "",
3044 (char *)m->gtktypes->data);
3045 gob_strdown (set_func);
3047 out_printf (out, "\t%s (&___return_val, (%s) (%s));\n",
3048 set_func, cast, defret);
3053 out_printf (out, "\n");
3056 s = g_strdup (m->id);
3059 out_printf(out, "\tg_signal_emitv (___param_values,\n"
3060 "\t\tobject_signals[%s_SIGNAL],\n"
3061 "\t\t0 /* detail */,\n"
3062 "\t\t&___return_val);\n", s);
3066 clear_signal_args (m);
3068 if (strcmp (m->gtktypes->data, "NONE") != 0) {
3069 char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
3071 /* Hack because glib is very very braindead */
3073 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
3074 strcmp ((char *)m->gtktypes->data, "BOXED") == 0 ||
3075 strcmp ((char *)m->gtktypes->data, "OBJECT") == 0 ||
3076 strcmp ((char *)m->gtktypes->data, "PARAM") == 0);
3078 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
3079 /* hack because glib is braindamaged */
3080 getfunc = g_strdup ("g_value_get_uint");
3082 getfunc = g_strdup_printf ("g_value_%s_%s",
3083 do_dup ? "dup" : "get",
3084 (char *)m->gtktypes->data);
3085 gob_strdown (getfunc);
3088 cast = get_type (m->mtype, TRUE);
3093 print_type (out, m->mtype, TRUE);
3095 " ___ret = (%s) %s (&___return_val);\n"
3096 "\t\tg_value_unset (&___return_val);\n"
3097 "\t\treturn ___ret;\n"
3104 out_printf(out, "}\n");
3109 out_addline_infile(out, m->line_no);
3110 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
3111 m, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE);
3112 print_method_body(m, FALSE, TRUE);
3113 /* the outfile line was added above */
3115 case VIRTUAL_METHOD:
3117 out_addline_infile(out, m->line_no);
3118 if(m->scope==PRIVATE_SCOPE)
3119 print_method(out, "static ", "\n", "", " ", "", "\n",
3120 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3121 else /* PUBLIC, PROTECTED */
3122 print_method(out, "", "\n", "", " ", "", "\n",
3123 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3124 out_printf(out, "{\n");
3125 out_addline_outfile(out);
3126 out_printf(out, "\t%sClass *klass;\n", typebase);
3127 print_preconditions(m);
3128 out_printf(out, "\tklass = %s_GET_CLASS(%s);\n\n"
3129 "\tif(klass->%s)\n",
3130 macrobase, ((FuncArg *)m->args->data)->name,
3132 if(strcmp(m->mtype->name, "void") == 0 &&
3133 m->mtype->pointer == NULL) {
3135 out_printf(out, "\t\t(*klass->%s)(%s",
3137 ((FuncArg *)m->args->data)->name);
3138 for(li=m->args->next;li;li=g_list_next(li)) {
3139 FuncArg *fa = li->data;
3140 out_printf(out, ",%s", fa->name);
3142 out_printf(out, ");\n}\n");
3145 out_printf(out, "\t\treturn (*klass->%s)(%s",
3147 ((FuncArg *)m->args->data)->name);
3148 for(li=m->args->next;li;li=g_list_next(li)) {
3149 FuncArg *fa = li->data;
3150 out_printf(out, ",%s", fa->name);
3152 out_printf(out, ");\n"
3155 print_type(out, m->mtype, TRUE);
3157 out_printf(out, ")(%s);\n}\n", m->defreturn);
3159 out_printf(out, ")(%s);\n}\n", m->onerror);
3161 out_printf(out, ")(0);\n}\n");
3167 out_addline_infile(out, m->line_no);
3168 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
3169 m, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE);
3170 print_method_body(m, FALSE, TRUE);
3171 /* the outfile line was added above */
3173 case OVERRIDE_METHOD:
3177 out_addline_infile(out, m->line_no);
3178 s = g_strdup_printf("\n___%x_", (guint)m->unique_id);
3179 print_method(out, "static ", s, "", " ", "", "\n",
3180 m, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE);
3182 out_addline_outfile(out);
3183 s = replace_sep(m->otype, '_');
3185 args = get_arg_names_for_macro(m);
3187 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
3188 "\t{ if(%s_CLASS(parent_class)->%s) \\\n"
3189 "\t\t(* %s_CLASS(parent_class)->%s)(%s); }\n",
3190 args, s, m->id, s, m->id, args);
3192 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
3193 "\t((%s_CLASS(parent_class)->%s)? \\\n"
3194 "\t\t(* %s_CLASS(parent_class)->%s)(%s): \\\n"
3196 args, s, m->id, s, m->id, args);
3197 out_printf(out, "(");
3198 print_type(out, m->mtype, TRUE);
3199 out_printf(out, ")%s))\n",
3200 m->onerror?m->onerror:"0");
3204 print_method_body(m, TRUE, TRUE);
3205 /* the outfile line was added above */
3206 out_printf(out, "#undef PARENT_HANDLER\n");
3208 case CONSTRUCTOR_METHOD:
3209 case DISPOSE_METHOD:
3210 case FINALIZE_METHOD:
3212 out_addline_infile(out, m->line_no);
3213 print_method(out, "static ", "\n", "", " ", "", "\n",
3214 m, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE);
3215 print_method_body(m, TRUE, TRUE);
3216 /* the outfile line was added above */
3225 char *outfile, *outfileh, *outfileph;
3227 outfilebase = g_strconcat (fullfilebase, for_cpp ? ".cc" : ".c", NULL);
3228 outfile = g_strconcat(outfilebase, no_touch ? "#gob#" : "", NULL);
3230 outfilehbase = g_strconcat (fullfilebase, ".h", NULL);
3231 outfileh = g_strconcat(outfilehbase, no_touch_headers ? "#gob#" : "", NULL);
3233 if ((privates > 0 || protecteds > 0 ||
3234 private_header == PRIVATE_HEADER_ALWAYS) &&
3235 private_header != PRIVATE_HEADER_NEVER) {
3236 char sep[2] = {0,0};
3239 outfilephbase = g_strconcat (fullfilebase, sep, "private.h", NULL);
3240 outfileph = g_strconcat (outfilephbase, no_touch ? "#gob#" : "", NULL);
3242 outfilephbase = NULL;
3248 out = fopen (outfile, "w");
3250 error_printf (GOB_ERROR, 0,
3251 "Cannot open outfile: %s", outfile);
3253 outh = fopen (outfileh, "w");
3255 error_printf (GOB_ERROR, 0,
3256 "Cannot open outfile: %s", outfileh);
3258 if (outfileph != NULL) {
3259 outph = fopen (outfileph, "w");
3260 if (outph == NULL) {
3261 error_printf (GOB_ERROR, 0,
3262 "Cannot open outfile: %s",
3270 put_argument_nongnu_wrappers (Class *c)
3274 if (get_properties < 0 && set_properties < 0)
3277 for (li = c->nodes; li != NULL; li = li->next) {
3279 const char *name, *gtktype;
3285 if (n->type == ARGUMENT_NODE) {
3286 Argument *a = (Argument *)n;
3288 gtktype = a->gtktype;
3290 get = a->get != NULL;
3291 set = a->set != NULL;
3292 } else if (n->type == PROPERTY_NODE) {
3293 Property *p = (Property *)n;
3295 gtktype = p->gtktype;
3297 get = p->get != NULL;
3298 set = p->set != NULL;
3303 aname = g_strdup (name);
3307 cast = get_type (atype, TRUE);
3309 cast = g_strdup (get_cast (gtktype, TRUE));
3313 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3314 "\"%s\",(%s)(arg)\n",
3315 macrobase, aname, name, cast);
3317 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3318 "\"%s\",(%s*)(arg)\n",
3319 macrobase, aname, name, cast);
3322 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3324 macrobase, aname, name);
3326 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3328 macrobase, aname, name);
3336 put_argument_gnu_wrappers(Class *c)
3340 if(get_properties < 0 && set_properties < 0)
3343 for (li = c->nodes; li != NULL; li = li->next) {
3345 const char *name, *gtktype;
3351 if (n->type == ARGUMENT_NODE) {
3352 Argument *a = (Argument *)n;
3354 gtktype = a->gtktype;
3356 get = a->get != NULL;
3357 set = a->set != NULL;
3358 } else if (n->type == PROPERTY_NODE) {
3359 Property *p = (Property *)n;
3361 gtktype = p->gtktype;
3363 get = p->get != NULL;
3364 set = p->set != NULL;
3369 aname = g_strdup (name);
3373 cast = get_type (atype, TRUE);
3375 cast = g_strdup (get_cast (gtktype, TRUE));
3379 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3380 "\"%s\", __extension__ ({%sz = (arg); z;})\n",
3381 macrobase, aname, name, cast);
3383 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3384 "\"%s\", __extension__ ({%s*z = (arg); z;})\n",
3385 macrobase, aname, name, cast);
3388 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3390 macrobase, aname, name);
3392 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3394 macrobase, aname, name);
3402 print_ccode_block(CCode *cc)
3405 switch(cc->cctype) {
3407 /* HT code is printed exactly like normal header
3408 code but is printed before */
3411 out_printf(fp, "\n");
3414 /* AT code is printed exactly like normal 'all'
3415 code but is printed before */
3418 out_printf(outph, "\n");
3419 out_printf(outph, "%s\n", cc->cbuf);
3420 out_addline_infile(outph, cc->line_no);
3421 out_addline_outfile(outph);
3423 out_printf(outh, "\n");
3424 out_printf(outh, "%s\n", cc->cbuf);
3426 out_printf(fp, "\n");
3427 out_addline_infile(fp, cc->line_no);
3433 out_printf(fp, "\n");
3434 out_addline_infile(fp, cc->line_no);
3441 out_printf(fp, "\n");
3442 out_addline_infile(fp, cc->line_no);
3445 out_printf(fp, "%s\n", cc->cbuf);
3446 if(cc->cctype == C_CCODE ||
3447 cc->cctype == AD_CCODE ||
3448 cc->cctype == A_CCODE ||
3449 cc->cctype == AT_CCODE ||
3450 cc->cctype == PH_CCODE)
3451 out_addline_outfile(fp);
3455 print_class_block(Class *c)
3459 gboolean printed_private = FALSE;
3463 out_printf(outph ? outph : outh, "#include <gtk/gtk.h>\n");
3464 out_printf(outph ? outph : outh, "#include <glade/glade-xml.h>\n\n");
3468 out_printf(out, "/* utility types we may need */\n");
3469 if(special_array[SPECIAL_2POINTER])
3470 out_printf(out, "typedef struct { "
3471 "gpointer a; gpointer b; "
3472 "} ___twopointertype;\n");
3473 if(special_array[SPECIAL_3POINTER])
3474 out_printf(out, "typedef struct { "
3475 "gpointer a; gpointer b; "
3477 "} ___threepointertype;\n");
3478 if(special_array[SPECIAL_INT_POINTER])
3479 out_printf(out, "typedef struct { "
3480 "gint a; gpointer b; "
3481 "} ___intpointertype;\n");
3482 out_printf(out, "\n");
3485 out_printf(outh, "\n/*\n"
3486 " * Type checking and casting macros\n"
3488 out_printf(outh, "#define %s\t"
3489 "(%s_get_type())\n",
3490 macrotype, funcbase);
3491 out_printf(outh, "#define %s(obj)\t"
3492 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s)\n",
3493 macrobase, funcbase, typebase);
3494 out_printf(outh, "#define %s_CONST(obj)\t"
3495 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s const)\n",
3496 macrobase, funcbase, typebase);
3497 out_printf(outh, "#define %s_CLASS(klass)\t"
3498 "G_TYPE_CHECK_CLASS_CAST((klass), %s_get_type(), %sClass)\n",
3499 macrobase, funcbase, typebase);
3500 out_printf(outh, "#define %s(obj)\t"
3501 "G_TYPE_CHECK_INSTANCE_TYPE((obj), %s_get_type ())\n\n",
3504 "#define %s_GET_CLASS(obj)\t"
3505 "G_TYPE_INSTANCE_GET_CLASS((obj), %s_get_type(), %sClass)\n",
3506 macrobase, funcbase, typebase);
3508 if ( ! no_self_alias) {
3509 out_printf(out, "/* self casting macros */\n");
3510 out_printf(out, "#define SELF(x) %s(x)\n", macrobase);
3511 out_printf(out, "#define SELF_CONST(x) %s_CONST(x)\n", macrobase);
3512 out_printf(out, "#define IS_SELF(x) %s(x)\n", macrois);
3513 out_printf(out, "#define TYPE_SELF %s\n", macrotype);
3514 out_printf(out, "#define SELF_CLASS(x) %s_CLASS(x)\n\n",
3516 out_printf(out, "#define SELF_GET_CLASS(x) %s_GET_CLASS(x)\n\n",
3519 out_printf(out, "/* self typedefs */\n");
3520 out_printf(out, "typedef %s Self;\n", typebase);
3521 out_printf(out, "typedef %sClass SelfClass;\n\n", typebase);
3525 always_private_struct) {
3526 out_printf (outh, "\n/* Private structure type */\n");
3527 out_printf (outh, "typedef struct _%sPrivate %sPrivate;\n",
3528 typebase, typebase);
3530 out_printf (outh, "/* There are no privates, this "
3531 "structure is thus never defined */\n");
3534 out_printf (outh, "\n/*\n"
3535 " * Main object structure\n"
3537 s = replace_sep (c->otype, '_');
3539 out_printf (outh, "#ifndef __TYPEDEF_%s__\n"
3540 "#define __TYPEDEF_%s__\n", s, s);
3542 out_printf (outh, "typedef struct _%s %s;\n"
3543 "#endif\n", typebase, typebase);
3544 out_printf (outh, "struct _%s {\n\t%s __parent__;\n",
3545 typebase, ptypebase);
3546 for (li = c->nodes; li; li=li->next) {
3547 static gboolean printed_public = FALSE;
3549 Variable *v = (Variable *)n;
3550 if(n->type == VARIABLE_NODE &&
3551 v->scope == PUBLIC_SCOPE) {
3552 if( ! printed_public) {
3553 out_printf(outh, "\t/*< public >*/\n");
3554 printed_public = TRUE;
3556 put_variable((Variable *)n, outh);
3559 /* put protecteds always AFTER publics */
3560 for (li = c->nodes; li != NULL; li = li->next) {
3562 Variable *v = (Variable *)n;
3563 if (n->type == VARIABLE_NODE &&
3564 v->scope == PROTECTED_SCOPE) {
3565 if ( ! printed_private) {
3566 out_printf (outh, "\t/*< private >*/\n");
3567 printed_private = TRUE;
3569 put_variable ((Variable *)n, outh);
3573 always_private_struct) {
3574 if ( ! printed_private)
3575 out_printf (outh, "\t/*< private >*/\n");
3576 out_printf (outh, "\t%sPrivate *_priv;\n", typebase);
3578 out_printf (outh, "};\n");
3583 /* if we are to stick this into the private
3584 header, if not stick it directly into the
3591 out_printf (outfp, "struct _%sPrivate {\n",
3595 for(li=c->nodes; li; li=li->next) {
3597 Variable *v = (Variable *)n;
3598 if(n->type == VARIABLE_NODE &&
3599 v->scope == PRIVATE_SCOPE) {
3600 out_addline_infile(outfp, v->line_no);
3601 put_variable(v, outfp);
3604 out_addline_outfile(outfp);
3606 out_printf(outfp, "};\n");
3609 out_printf(outh, "\n/*\n"
3610 " * Class definition\n"
3612 out_printf(outh, "typedef struct _%sClass %sClass;\n",
3613 typebase, typebase);
3615 "struct _%sClass {\n\t%sClass __parent__;\n",
3616 typebase, ptypebase);
3617 for(li = c->nodes; li != NULL; li = li->next) {
3619 if(n->type == METHOD_NODE)
3620 put_vs_method((Method *)n);
3622 /* If BonoboX type class put down the epv */
3623 if (c->bonobo_object_class != NULL) {
3625 "\t/* Bonobo object epv */\n"
3626 "\tPOA_%s__epv _epv;\n",
3627 c->bonobo_object_class);
3629 /* put class scope variables */
3630 for (li = c->nodes; li != NULL; li = li->next) {
3632 Variable *v = (Variable *)n;
3633 if (n->type == VARIABLE_NODE &&
3634 v->scope == CLASS_SCOPE)
3635 put_variable ((Variable *)n, outh);
3637 out_printf (outh, "};\n\n");
3639 out_printf (out, "/* here are local prototypes */\n");
3640 if (set_properties > 0) {
3641 out_printf (out, "static void ___object_set_property "
3642 "(GObject *object, guint property_id, "
3643 "const GValue *value, GParamSpec *pspec);\n");
3645 if (get_properties > 0) {
3646 out_printf (out, "static void ___object_get_property "
3647 "(GObject *object, guint property_id, "
3648 "GValue *value, GParamSpec *pspec);\n");
3651 out_printf (outh, "\n/*\n"
3652 " * Public methods\n"
3655 if ( ! overrode_get_type) {
3656 out_printf (outh, "GType\t%s_get_type\t(void) G_GNUC_CONST;\n", funcbase);
3659 for(li = c->nodes; li != NULL; li = li->next) {
3661 if(n->type == METHOD_NODE) {
3662 put_pub_method((Method *)n);
3663 put_prot_method((Method *)n);
3664 put_priv_method_prot((Method *)n);
3668 /* this idea is less and less apealing to me */
3670 out_printf (outh, "\n/*\n"
3671 " * Signal connection wrapper macros\n"
3674 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3675 put_signal_macros (c, TRUE);
3676 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3677 put_signal_macros (c, FALSE);
3678 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n");
3680 put_signal_macros (c, FALSE);
3681 out_printf(outh, "\n");
3684 out_printf (out, "\n/*\n"
3685 " * Signal connection wrapper macro shortcuts\n"
3687 put_local_signal_macros (c);
3688 out_printf(outh, "\n");
3691 /* argument wrapping macros */
3692 if(get_properties > 0 || set_properties > 0) {
3693 out_printf(outh, "\n/*\n"
3694 " * Argument wrapping macros\n"
3697 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3698 put_argument_gnu_wrappers(c);
3699 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3700 put_argument_nongnu_wrappers(c);
3701 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n");
3703 put_argument_nongnu_wrappers(c);
3708 for(li = c->nodes; li != NULL; li = li->next) {
3710 if(n->type == METHOD_NODE)
3711 add_signal_prots((Method *)n);
3717 if(any_method_to_alias(c)) {
3718 out_printf (out, "/* Short form macros */\n");
3719 make_method_aliases (c);
3722 add_interface_inits (c);
3724 if ( ! overrode_get_type) {
3725 if (c->bonobo_object_class != NULL)
3726 add_bonobo_object_get_type ();
3731 out_printf (out, "/* a macro for creating a new object of our type */\n");
3733 "#define GET_NEW ((%s *)g_object_new(%s_get_type(), NULL))\n\n",
3734 typebase, funcbase);
3736 out_printf (out, "/* a function for creating a new object of our type */\n");
3737 out_printf (out, "#include <stdarg.h>\n");
3739 "static %s * GET_NEW_VARG (const char *first, ...)%s;\n"
3740 "static %s *\nGET_NEW_VARG (const char *first, ...)\n"
3741 "{\n\t%s *ret;\n\tva_list ap;\n"
3742 "\tva_start (ap, first);\n"
3743 "\tret = (%s *)g_object_new_valist (%s_get_type (), "
3746 "\treturn ret;\n}\n\n",
3748 no_gnu ? "" : " G_GNUC_UNUSED",
3749 typebase, typebase, typebase, funcbase);
3753 out_printf (out, "/* a function to connect glade callback */\n");
3754 out_printf (out,"static void\n"
3755 "___glade_xml_connect_foreach(const gchar *handler_name,\n"
3756 "GObject *object,\n"
3757 "const gchar *signal_name,\n"
3758 "const gchar *signal_data,\n"
3759 "GObject *connect_object,\n"
3761 "gpointer user_data)\n"
3763 "\tstatic GModule * allsymbols = NULL;\n"
3765 "\tif (!allsymbols) allsymbols = g_module_open(NULL, 0);\n"
3766 "\tif (allsymbols) {\n"
3767 "\t\tgchar * func_name = g_strdup_printf(\"%s_%%s\", handler_name);\n"
3768 "\t\tGCallback func;\n"
3770 "\t\tif (!g_module_symbol(allsymbols, func_name, (gpointer)&func)){\n"
3771 "\t\t\tif (!g_module_symbol(allsymbols, handler_name, (gpointer)&func)) {\n"
3772 "\t\t\t\tg_warning(\"could not find signal handler '%%s'.\", func_name);\n"
3773 "\t\t\t\tg_free(func_name);\n"
3778 "\t\t\tg_signal_connect_data(object, signal_name, func, user_data, NULL, G_CONNECT_AFTER | G_CONNECT_SWAPPED);\n"
3780 "\t\t\tg_signal_connect_data(object, signal_name, func, user_data, NULL, G_CONNECT_SWAPPED);\n"
3781 "\t\tg_free(func_name);\n"
3788 for (li = nodes; li != NULL; li = li->next) {
3789 Node *node = li->data;
3790 if (node->type == CCODE_NODE) {
3791 CCode *cc = (CCode *)node;
3792 if (cc->cctype == AD_CCODE)
3793 print_ccode_block (cc);
3797 if (need_constructor)
3798 add_constructor (c);
3808 if(set_properties > 0) {
3809 add_getset_arg(c, TRUE);
3812 if(get_properties > 0) {
3813 add_getset_arg(c, FALSE);
3816 for(li = c->nodes; li != NULL; li = li->next) {
3818 if(n->type == METHOD_NODE)
3819 put_method((Method *)n);
3822 add_bad_hack_to_avoid_unused_warnings(c);
3826 print_useful_macros(void)
3828 int major = 0, minor = 0, pl = 0;
3831 sscanf (VERSION, "%d.%d.%d", &major, &minor, &pl);
3832 out_printf (out, "#define GOB_VERSION_MAJOR %d\n", major);
3833 out_printf (out, "#define GOB_VERSION_MINOR %d\n", minor);
3834 out_printf (out, "#define GOB_VERSION_PATCHLEVEL %d\n\n", pl);
3836 /* Useful priv macro thingie */
3837 /* FIXME: this should be done the same way that priv is, as a var,
3839 out_printf (out, "#define selfp (self->_priv)\n\n");
3843 print_more_useful_macros (void)
3846 out_printf (out, "#define ___GOB_LIKELY(expr) (expr)\n");
3847 out_printf (out, "#define ___GOB_UNLIKELY(expr) (expr)\n");
3849 out_printf (out, "#ifdef G_LIKELY\n");
3850 out_printf (out, "#define ___GOB_LIKELY(expr) G_LIKELY(expr)\n");
3851 out_printf (out, "#define ___GOB_UNLIKELY(expr) G_UNLIKELY(expr)\n");
3852 out_printf (out, "#else /* ! G_LIKELY */\n");
3853 out_printf (out, "#define ___GOB_LIKELY(expr) (expr)\n");
3854 out_printf (out, "#define ___GOB_UNLIKELY(expr) (expr)\n");
3855 out_printf (out, "#endif /* G_LIKELY */\n");
3860 print_file_comments(void)
3862 out_printf(outh, "/* Generated by GOB (v%s)"
3863 " (do not edit directly) */\n\n", VERSION);
3865 out_printf(outph, "/* Generated by GOB (v%s)"
3866 " (do not edit directly) */\n\n", VERSION);
3867 out_printf(out, "/* Generated by GOB (v%s)"
3868 " (do not edit directly) */\n\n", VERSION);
3870 out_printf(out, "/* End world hunger, donate to the World Food Programme, http://www.wfp.org */\n\n");
3874 print_includes(void)
3876 gboolean found_header;
3879 /* We may need string.h for memset */
3880 if ( ! g_list_find_custom(include_files, "string.h", (GCompareFunc)strcmp)) {
3881 out_printf(out, "#include <string.h> /* memset() */\n\n");
3884 p = g_strconcat(filebase, ".h", NULL);
3885 found_header = TRUE;
3886 if( ! g_list_find_custom(include_files, p, (GCompareFunc)strcmp)) {
3887 out_printf(out, "#include \"%s.h\"\n\n", filebase);
3888 found_header = FALSE;
3892 /* if we are creating a private header see if it was included */
3894 char sep[2] = {0,0};
3897 p = g_strconcat(filebase, sep, "private.h", NULL);
3898 if( ! g_list_find_custom(include_files, p,
3899 (GCompareFunc)strcmp)) {
3900 out_printf(out, "#include \"%s%sprivate.h\"\n\n",
3904 error_printf(GOB_WARN, 0,
3905 "Implicit private header include "
3907 "\tsource file, while public "
3908 "header is at a custom location, "
3910 "\texplicitly include "
3911 "the private header below the "
3919 print_header_prefixes(void)
3923 p = replace_sep(((Class *)class)->otype, '_');
3925 out_printf(outh, "#ifndef __%s_H__\n#define __%s_H__\n\n", p, p);
3927 out_printf(outph, "#ifndef __%s_PRIVATE_H__\n"
3928 "#define __%s_PRIVATE_H__\n\n"
3929 "#include \"%s.h\"\n\n", p, p, filebase);
3932 if( ! no_extern_c) {
3933 out_printf(outh, "#ifdef __cplusplus\n"
3935 "#endif /* __cplusplus */\n\n");
3937 out_printf(outph, "#ifdef __cplusplus\n"
3939 "#endif /* __cplusplus */\n\n");
3944 print_header_postfixes(void)
3947 out_printf(outh, "\n#ifdef __cplusplus\n"
3949 "#endif /* __cplusplus */\n");
3950 out_printf(outh, "\n#endif\n");
3953 out_printf(outph, "\n#ifdef __cplusplus\n"
3955 "#endif /* __cplusplus */\n");
3956 out_printf(outph, "\n#endif\n");
3965 /* print the AT_CCODE and CT_CCODE blocks */
3966 for(li = nodes; li != NULL; li = li->next) {
3967 Node *node = li->data;
3968 if(node->type == CCODE_NODE) {
3969 CCode *cc = (CCode *)node;
3970 if (cc->cctype == AT_CCODE ||
3971 cc->cctype == CT_CCODE)
3972 print_ccode_block((CCode *)node);
3978 print_header_top(void)
3982 /* mandatory includes */
3983 out_printf (outh, "#include <glib.h>\n");
3984 out_printf (outh, "#include <glib-object.h>\n");
3986 /* print the HT_CCODE blocks */
3987 for (li = nodes; li != NULL; li = li->next) {
3988 Node *node = li->data;
3989 if (node->type == CCODE_NODE) {
3990 CCode *cc = (CCode *)node;
3991 if (cc->cctype == HT_CCODE)
3992 print_ccode_block ((CCode *)node);
3998 print_enum (EnumDef *enode)
4005 funcprefix = replace_sep (enode->etype, '_');
4006 gob_strdown (funcprefix);
4007 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
4009 type = remove_sep (enode->etype);
4011 out_printf (outh, "\ntypedef enum {\n");
4013 for (li = enode->values; li != NULL; li = li->next) {
4014 EnumValue *value = li->data;
4016 char *sname = gob_strdown (g_strdup (value->name));
4018 while ((p = strchr (sname, '_')) != NULL)
4021 out_printf (outh, "\t%s_%s", enode->prefix, value->name);
4022 if (value->value != NULL)
4023 out_printf (outh, " = %s", value->value);
4024 if (li->next != NULL)
4025 out_printf (outh, ",\n");
4027 out_printf (outh, "\n");
4029 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
4030 enode->prefix, value->name,
4031 enode->prefix, value->name,
4037 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
4039 out_printf (outh, "} %s;\n", type);
4041 str = make_pre_macro (enode->etype, "TYPE");
4042 out_printf (outh, "#define %s ", str);
4045 out_printf (outh, "%s_get_type()\n", funcprefix);
4046 out_printf (outh, "GType %s_get_type (void) G_GNUC_CONST;\n\n", funcprefix);
4049 "GType\n%s_get_type (void)\n"
4051 "\tstatic GType type = 0;\n"
4052 "\tif ___GOB_UNLIKELY(type == 0)\n"
4053 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
4056 funcprefix, type, funcprefix);
4058 g_free (funcprefix);
4063 print_flags (Flags *fnode)
4071 funcprefix = replace_sep (fnode->ftype, '_');
4072 gob_strdown (funcprefix);
4073 out_printf (out, "static const GFlagsValue _%s_values[] = {\n",
4075 type = remove_sep (fnode->ftype);
4077 out_printf (outh, "\ntypedef enum {\n");
4079 for (i = 0, li = fnode->values; li != NULL; i++, li = li->next) {
4080 const char *name = li->data;
4082 char *sname = gob_strdown (g_strdup (name));
4084 while ((p = strchr (sname, '_')) != NULL)
4087 out_printf (outh, "\t%s_%s = 1<<%d",
4088 fnode->prefix, name, i);
4089 if (li->next != NULL)
4090 out_printf (outh, ",\n");
4092 out_printf (outh, "\n");
4094 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
4095 fnode->prefix, name,
4096 fnode->prefix, name,
4102 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
4104 out_printf (outh, "} %s;\n", type);
4106 str = make_pre_macro (fnode->ftype, "TYPE");
4107 out_printf (outh, "#define %s ", str);
4110 out_printf (outh, "%s_get_type()\n", funcprefix);
4111 out_printf (outh, "GType %s_get_type (void) G_GNUC_CONST;\n\n", funcprefix);
4114 "GType\n%s_get_type (void)\n"
4116 "\tstatic GType type = 0;\n"
4117 "\tif ___GOB_UNLIKELY(type == 0)\n"
4118 "\t\ttype = g_flags_register_static (\"%s\", _%s_values);\n"
4121 funcprefix, type, funcprefix);
4123 g_free (funcprefix);
4128 print_error (Error *enode)
4135 funcprefix = replace_sep (enode->etype, '_');
4136 gob_strdown (funcprefix);
4137 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
4139 type = remove_sep (enode->etype);
4141 out_printf (outh, "\ntypedef enum {\n");
4143 for (li = enode->values; li != NULL; li = li->next) {
4144 const char *name = li->data;
4146 char *sname = gob_strdown (g_strdup (name));
4148 while ((p = strchr (sname, '_')) != NULL)
4151 out_printf (outh, "\t%s_%s", enode->prefix, name);
4152 if (li->next != NULL)
4153 out_printf (outh, ",\n");
4155 out_printf (outh, "\n");
4157 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
4158 enode->prefix, name,
4159 enode->prefix, name,
4165 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
4167 out_printf (outh, "} %s;\n", type);
4169 str = make_pre_macro (enode->etype, "TYPE");
4170 out_printf (outh, "#define %s ", str);
4173 out_printf (outh, "%s_get_type ()\n", funcprefix);
4174 out_printf (outh, "GType %s_get_type (void) G_GNUC_CONST;\n\n", funcprefix);
4177 "GType\n%s_get_type (void)\n"
4179 "\tstatic GType type = 0;\n"
4180 "\tif ___GOB_UNLIKELY(type == 0)\n"
4181 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
4184 funcprefix, type, funcprefix);
4186 out_printf (outh, "#define %s %s_quark ()\n", enode->prefix, funcprefix);
4187 out_printf (outh, "GQuark %s_quark (void);\n\n", funcprefix);
4189 str = replace_sep (enode->etype, '-');
4193 "GQuark\n%s_quark (void)\n"
4195 "\tstatic GQuark q = 0;\n"
4197 "\t\tq = g_quark_from_static_string (\"%s\");\n"
4204 g_free (funcprefix);
4209 generate_outfiles(void)
4213 print_file_comments();
4219 print_header_prefixes();
4221 print_useful_macros();
4225 print_more_useful_macros ();
4227 for (li = nodes; li != NULL; li = li->next) {
4228 Node *node = li->data;
4229 if (node->type == CCODE_NODE) {
4230 CCode *cc = (CCode *)node;
4231 if (cc->cctype != HT_CCODE &&
4232 cc->cctype != AT_CCODE &&
4233 cc->cctype != AD_CCODE)
4234 print_ccode_block ((CCode *)node);
4235 } else if (node->type == CLASS_NODE) {
4236 print_class_block ((Class *)node);
4237 } else if (node->type == ENUMDEF_NODE) {
4238 print_enum ((EnumDef *)node);
4239 } else if (node->type == FLAGS_NODE) {
4240 print_flags ((Flags *)node);
4241 } else if (node->type == ERROR_NODE) {
4242 print_error ((Error *)node);
4244 g_assert_not_reached();
4248 print_header_postfixes();
4254 fprintf(stderr, "Gob version %s\n\n", VERSION);
4255 fprintf(stderr, "gob [options] file.gob\n\n");
4256 fprintf(stderr, "Options:\n"
4257 "\t--help,-h,-? Display this help\n"
4258 "\t--version Display version\n"
4259 "\t--exit-on-warn,-w Exit with an error on warnings\n"
4260 "\t--no-exit-on-warn Don't exit on warnings [default]\n"
4261 "\t--for-cpp Create C++ files\n"
4262 "\t--no-extern-c Never print extern \"C\" into the "
4264 "\t--no-gnu Never use GNU extentions\n"
4265 "\t--no-touch Don't touch output files unless they "
4267 "\t changed (implies --no-touch-headers)\n"
4268 "\t--no-touch-headers Don't touch headers unless they "
4270 "\t--always-private-header Always create a private header "
4272 "\t even if it would be empty\n"
4273 "\t--ondemand-private-header Create private header only when "
4276 "\t--no-private-header Don't create a private header, "
4278 "\t structure and protected "
4279 "prototypes inside c file\n"
4280 "\t--always-private-struct Always create a private pointer "
4282 "\t the object structure\n"
4283 "\t--m4 Preprocess source with m4. "
4284 "Following args will\n"
4285 "\t be passed to m4\n"
4286 "\t--m4-dir Print directory that will be "
4289 "\t--no-write,-n Don't write output files, just "
4291 "\t--no-lines Don't print '#line' to output\n"
4292 "\t--no-self-alias Don't create self type and macro "
4294 "\t--no-kill-underscores Ignored for compatibility\n"
4295 "\t-o,--output-dir The directory where output "
4296 "should be placed\n"
4297 "\t--file-sep[=c] replace default \'-\' file "
4298 "name separator\n\n"
4299 "\t--gtk3 Use gtk+3\n"
4301 fprintf(stderr, "End world hunger, donate to the World Food Programme, http://www.wfp.org\n");
4305 parse_options(int argc, char *argv[])
4308 int got_file = FALSE;
4309 int no_opts = FALSE;
4310 int m4_opts = FALSE; /* if we are just passing on args to m4 */
4314 for(i = 1 ; i < argc; i++) {
4316 char *new_commandline;
4317 g_assert(m4_commandline!=NULL);
4319 /* check whether this one looks like the filename */
4320 if((!strcmp(argv[i],"-") || argv[i][0] != '-')
4322 const gchar *m4_flags=use_m4_clean?"":M4_FLAGS;
4326 /* insert flags before the filename */
4327 new_commandline=g_strconcat(m4_commandline,
4335 /* just an ordinary option */
4337 new_commandline=g_strconcat(m4_commandline,
4342 /* free old commandline */
4343 g_free(m4_commandline);
4344 m4_commandline=new_commandline;
4346 } else if(no_opts ||
4347 argv[i][0] != '-') {
4350 fprintf(stderr, "Specify only one file!\n");
4356 } else if(strcmp(argv[i], "--help")==0) {
4359 } else if(strcmp(argv[i], "--version")==0) {
4360 fprintf(stderr, "Gob version %s\n", VERSION);
4362 } else if(strcmp(argv[i], "--exit-on-warn")==0) {
4363 exit_on_warn = TRUE;
4364 } else if(strcmp(argv[i], "--no-exit-on-warn")==0) {
4365 exit_on_warn = FALSE;
4366 } else if(strcmp(argv[i], "--for-cpp")==0) {
4368 } else if(strcmp(argv[i], "--no-touch")==0) {
4370 no_touch_headers = TRUE;
4371 } else if(strcmp(argv[i], "--no-touch-headers")==0) {
4372 no_touch_headers = TRUE;
4373 } else if(strcmp(argv[i], "--ondemand-private-header")==0) {
4374 private_header = PRIVATE_HEADER_ONDEMAND;
4375 } else if(strcmp(argv[i], "--always-private-header")==0) {
4376 private_header = PRIVATE_HEADER_ALWAYS;
4377 } else if(strcmp(argv[i], "--no-private-header")==0) {
4378 private_header = PRIVATE_HEADER_NEVER;
4379 } else if(strcmp(argv[i], "--no-gnu")==0) {
4381 } else if(strcmp(argv[i], "--no-extern-c")==0) {
4383 } else if(strcmp(argv[i], "--no-write")==0) {
4385 } else if(strcmp(argv[i], "--no-lines")==0) {
4387 } else if(strcmp(argv[i], "--no-self-alias")==0) {
4388 no_self_alias = TRUE;
4389 } else if(strcmp(argv[i], "--no-kill-underscores")==0) {
4391 } else if(strcmp(argv[i], "--always-private-struct")==0) {
4392 always_private_struct = TRUE;
4393 } else if(strcmp(argv[i], "--m4-dir")==0) {
4394 printf("%s\n",M4_INCLUDE_DIR);
4396 } else if(strcmp(argv[i], "--m4")==0) {
4400 m4_commandline=g_strdup(M4_COMMANDLINE);
4401 } else if(strcmp(argv[i], "--m4-clean")==0) {
4405 m4_commandline=g_strdup(M4_COMMANDLINE);
4406 } else if (strcmp (argv[i], "-o") == 0 ||
4407 strcmp (argv[i], "--output-dir") == 0) {
4409 output_dir = g_strdup (argv[i+1]);
4414 } else if (strncmp (argv[i], "-o=", strlen ("-o=")) == 0 ||
4417 strlen ("--output-dir=")) == 0) {
4418 char *p = strchr (argv[i], '=');
4419 g_assert (p != NULL);
4420 output_dir = g_strdup (p+1);
4421 } else if (strncmp (argv[i], "--file-sep=",
4422 strlen ("--file-sep=")) == 0) {
4423 char *p = strchr (argv[i], '=');
4424 g_assert (p != NULL);
4426 } else if (strncmp (argv[i], "--file-sep",
4427 strlen ("--file-sep")) == 0) {
4429 file_sep = (argv[i+1])[0];
4434 } else if(strcmp(argv[i], "--gtk3")==0) {
4436 } else if(strcmp(argv[i], "--")==0) {
4437 /*further arguments are files*/
4439 } else if(strncmp(argv[i], "--", 2)==0) {
4440 /*unknown long option*/
4441 fprintf(stderr, "Unknown option '%s'!\n", argv[i]);
4445 /*by now we know we have a string starting with
4446 - which is a short option string*/
4448 for(p = argv[i] + 1; *p; p++) {
4462 "Unknown option '%c'!\n", *p);
4471 /* if we are using m4, and got no filename, append m4 flags now */
4472 if(!got_file && use_m4 && !use_m4_clean) {
4473 char *new_commandline;
4474 new_commandline=g_strconcat(m4_commandline,
4478 g_free(m4_commandline);
4479 m4_commandline=new_commandline;
4485 compare_and_move (const char *old_filename)
4487 char *new_filename = g_strconcat (old_filename, "#gob#", NULL);
4489 gboolean equal = FALSE;
4491 old_f = fopen (old_filename, "r");
4494 gboolean error = FALSE;
4496 new_f = fopen (new_filename, "r");
4505 new_n = fread (new_buf, 1, sizeof (new_buf), new_f);
4506 if (ferror (new_f)) {
4508 error_printf (GOB_ERROR, 0,
4509 "Can't read %s: %s",
4511 g_strerror (errno));
4515 old_n = fread (old_buf, 1, sizeof (old_buf), old_f);
4517 || feof (new_f) != feof (old_f)
4519 || memcmp (new_buf, old_buf, new_n) != 0)
4528 error_printf (GOB_ERROR, 0, "Can't open %s: %s",
4529 new_filename, g_strerror (errno));
4537 if (! equal && unlink (old_filename) != 0) {
4538 error_printf (GOB_ERROR, 0, "Can't remove %s: %s",
4539 old_filename, g_strerror (errno));
4545 if (unlink (new_filename) != 0)
4546 error_printf (GOB_ERROR, 0, "Can't remove %s: %s",
4547 new_filename, g_strerror (errno));
4549 if (rename (new_filename, old_filename) != 0)
4550 error_printf (GOB_ERROR, 0, "Can't rename %s to %s: %s",
4551 new_filename, old_filename,
4552 g_strerror (errno));
4556 g_free (new_filename);
4560 main(int argc, char *argv[])
4562 parse_options(argc, argv);
4565 yyin = popen(m4_commandline, "r");
4567 fprintf(stderr, "Error: can't open pipe from '%s'\n",
4571 } else if(filename) {
4572 yyin = fopen(filename, "r");
4574 fprintf(stderr, "Error: can't open file '%s'\n",
4583 /* This is where parsing is done */
4586 error_print (GOB_ERROR, 0, "Parsing errors, quitting");
4588 /* close input file */
4589 if(use_m4) pclose(yyin);
4594 error_print (GOB_ERROR, 0, "no class defined");
4597 exit_on_error = FALSE;
4599 signals = count_signals ((Class *)class);
4600 set_properties = count_set_properties ((Class *)class) +
4601 count_set_arguments ((Class *)class);
4602 get_properties = count_get_properties ((Class *)class) +
4603 count_get_arguments ((Class *)class);
4604 overrides = count_overrides ((Class *)class);
4605 privates = count_privates ((Class *)class);
4606 protecteds = count_protecteds ((Class *)class);
4607 unreftors = count_unreftors ((Class *)class);
4608 destructors = count_destructors ((Class *)class);
4609 initializers = count_initializers ((Class *)class);
4610 glade_widgets = count_glade_widgets ((Class *)class);
4611 overrode_get_type = find_get_type ((Class *)class);
4614 make_inits ((Class *)class);
4616 find_constructor ((Class *)class);
4617 if (user_constructor != NULL)
4618 need_constructor = TRUE;
4620 find_dispose ((Class *)class);
4621 if (unreftors > 0 ||
4622 dispose_handler != NULL ||
4623 user_dispose_method != NULL)
4624 need_dispose = TRUE;
4626 find_finalize ((Class *)class);
4627 if (destructors > 0 ||
4629 user_finalize_method != NULL) {
4630 need_finalize = TRUE;
4633 check_bad_symbols ((Class *)class);
4634 check_duplicate_symbols ((Class *)class);
4635 check_duplicate_overrides ((Class *)class);
4636 check_duplicate_signals_args ((Class *)class);
4637 check_public_new ((Class *)class);
4638 check_vararg ((Class *)class);
4639 check_firstarg ((Class *)class);
4640 check_nonvoidempty ((Class *)class);
4641 check_signal_args ((Class *)class);
4642 check_property_types ((Class *)class);
4643 check_argument_types ((Class *)class);
4644 check_func_arg_checks ((Class *)class);
4645 check_func_attrs ((Class *)class);
4646 check_for_class_destructors ((Class *)class);
4648 exit_on_error = TRUE;
4653 any_special = setup_special_array ((Class *)class, special_array);
4657 generate_outfiles ();
4668 compare_and_move (outfilebase);
4670 compare_and_move (outfilephbase);
4672 if (no_touch_headers)
4673 compare_and_move (outfilehbase);