2 * Copyright (C) 1999,2000 the Free Software Foundation.
3 * Copyright (C) 2000 Eazel, Inc.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
32 #include "treefuncs.h"
40 char *filename = NULL;
49 extern GList *include_files;
51 extern GHashTable *gtk_doc_hash;
54 static char *funcbase;
55 static char *pfuncbase;
56 static char *macrobase;
58 static char *macrotype;
59 static char *typebase;
60 static char *ptypebase;
62 static int signals = 0; /* number of signals */
63 static int set_arguments = 0; /* number of named (set) arguments */
64 static int get_arguments = 0; /* number of named (get) arguments */
65 static int overrides = 0; /* number of override methods */
66 static int privates = 0; /* number of private data members */
67 static int protecteds = 0; /* number of protected methods */
68 static int destructors = 0; /* number of variable destructors */
69 static int initializers = 0; /* number of variable initializers */
70 static gboolean overrode_get_type = FALSE; /* provided your won _get_type */
72 static gboolean made_aliases = FALSE; /* if we made any shorthand aliases
73 and need the REALLY UGLY HACK to
76 /* the special variable types we need to define */
77 static gboolean special_array[SPECIAL_LAST] = {0};
78 static gboolean any_special = FALSE;
80 static gboolean need_destroy = FALSE;
81 static Method * destroy_handler = NULL;
83 static gboolean need_finalize = FALSE;
84 static Method * finalize_handler = NULL;
91 gboolean no_touch_headers = FALSE;
92 gboolean for_cpp = FALSE;
93 gboolean no_gnu = FALSE;
94 gboolean exit_on_warn = FALSE;
95 gboolean exit_on_error = TRUE;
96 gboolean got_error = FALSE;
97 gint private_header = PRIVATE_HEADER_ONDEMAND;
98 gboolean no_extern_c = FALSE;
99 gboolean no_write = FALSE;
100 gboolean no_lines = FALSE;
101 gboolean no_self_alias = FALSE;
102 gboolean no_kill_underscores = FALSE;
103 gboolean always_private_struct = FALSE;
105 int method_unique_id = 1;
110 filebase = replace_sep(((Class *)class)->otype, '-');
113 funcbase = replace_sep(((Class *)class)->otype, '_');
116 pfuncbase = replace_sep(((Class *)class)->ptype, '_');
117 g_strdown(pfuncbase);
119 macrobase = replace_sep(((Class *)class)->otype, '_');
122 macrois = make_pre_macro(((Class *)class)->otype, "IS");
123 macrotype = make_pre_macro(((Class *)class)->otype, "TYPE");
125 typebase = remove_sep(((Class *)class)->otype);
127 ptypebase = remove_sep(((Class *)class)->ptype);
131 get_type(const Type *t, gboolean postfix_to_stars)
138 s = remove_sep(t->name);
139 gs = g_string_new(s);
143 if(postfix_to_stars) {
145 /*XXX: this is ugly perhaps we can do this whole postfix thing
146 in a nicer way, we just count the number of '[' s and from
147 that we deduce the number of dimensions, so that we can print
149 for(p=t->postfix; p && *p; p++)
150 if(*p == '[') extra++;
152 g_string_append_c(gs, ' ');
155 g_string_append(gs, t->pointer);
156 for(i=0; i < extra; i++)
157 g_string_append_c(gs, '*');
158 g_string_append_c(gs, ' ');
162 g_string_free(gs, FALSE);
167 get_gtk_doc(const char *id)
174 val = g_hash_table_lookup(gtk_doc_hash, id);
176 return g_strdup_printf("/**\n * %s_%s:\n%s **/\n",
177 funcbase, get_real_id(id), val);
178 val = g_hash_table_lookup(gtk_doc_hash, get_real_id(id));
180 return g_strdup_printf("/**\n * %s_%s:\n%s **/\n",
181 funcbase, get_real_id(id), val);
186 print_type(FILE *fp, const Type *t, gboolean postfix_to_stars)
190 s = get_type(t, postfix_to_stars);
191 out_printf(fp, "%s", s);
197 print_method (FILE *fp,
198 const char *typeprefix,
199 const char *nameprefix,
200 const char *subnameprefix,
201 const char *namepostfix,
202 const char *afterargs,
205 gboolean one_arg_per_line,
206 gboolean no_funcbase,
207 gboolean kill_underscore)
212 out_printf(fp, "%s", typeprefix);
213 print_type(fp, m->mtype, TRUE);
216 id = get_real_id(m->id);
221 out_printf(fp, "%s%s%s%s(",
222 nameprefix, subnameprefix, id, namepostfix);
224 out_printf(fp, "%s%s_%s%s%s(",
225 nameprefix, funcbase, subnameprefix, id,
229 for(li=m->args; li; li=g_list_next(li)) {
230 FuncArg *arg = li->data;
231 print_type(fp, arg->atype, FALSE);
233 out_printf(fp, "%s%s,%s", arg->name,
234 arg->atype->postfix ?
235 arg->atype->postfix : "",
236 one_arg_per_line ? "\n\t\t\t\t\t" : " ");
238 out_printf(fp, "%s%s", arg->name,
239 arg->atype->postfix ?
240 arg->atype->postfix : "");
243 out_printf(fp, ",%s...",
244 one_arg_per_line ? "\n\t\t\t\t\t" : " ");
246 out_printf(fp, "void");
248 out_printf(fp, "%s)%s", afterargs, postfix);
252 any_method_to_alias(Class *c)
256 for(li=c->nodes;li;li=g_list_next(li)) {
257 Node *node = li->data;
258 if(node->type == METHOD_NODE) {
259 Method *m = (Method *)node;
261 if(m->method == INIT_METHOD ||
262 m->method == CLASS_INIT_METHOD ||
263 m->method == OVERRIDE_METHOD)
273 /* just the vararg macros, we use the same func pointers for these as in non-gnu */
275 make_method_gnu_aliases(Class *c)
279 for(li = c->nodes; li != NULL; li = li->next) {
280 Node *node = li->data;
281 if(node->type == METHOD_NODE) {
282 Method *m = (Method *)node;
284 if(m->method == INIT_METHOD ||
285 m->method == CLASS_INIT_METHOD ||
286 m->method == OVERRIDE_METHOD)
289 /* in C++ mode don't alias new */
290 if(for_cpp && strcmp(m->id, "new")==0)
294 out_printf(out, "#define %s(args...) "
295 "%s_%s(args)\n", m->id,
296 funcbase, get_real_id(m->id));
298 out_printf(out, "#define %s() "
300 funcbase, get_real_id(m->id));
306 make_method_nongnu_aliases(Class *c)
310 gboolean local_made_aliases = FALSE;
312 for(li=c->nodes; li; li=g_list_next(li)) {
313 Node *node = li->data;
314 if(node->type == METHOD_NODE) {
315 Method *m = (Method *)node;
317 if(m->method == INIT_METHOD ||
318 m->method == CLASS_INIT_METHOD ||
319 m->method == OVERRIDE_METHOD)
322 /* in C++ mode don't alias new */
323 if(for_cpp && strcmp(m->id, "new")==0)
326 if( ! local_made_aliases)
327 out_printf(out, "\n/* Short form pointers */\n");
329 print_method(out, "static ", "(* const ", "", ") ",
331 m, FALSE, TRUE, FALSE);
332 out_printf(out, " = %s_%s;\n", funcbase,
335 local_made_aliases = TRUE;
338 if(local_made_aliases) {
339 out_printf(out, "\n");
345 add_bad_hack_to_avoid_unused_warnings(Class *c)
349 /* if we haven't had any methods, just return */
354 out_printf(out, "\n\n#if (!defined __GNUC__) || (defined __GNUC__ && defined __STRICT_ANSI__)\n");
356 "/*REALLY BAD HACK\n"
357 " This is to avoid unused warnings if you don't call\n"
358 " some method. I need to find a better way to do\n"
359 " this, not needed in GCC since we use some gcc\n"
360 " extentions to make saner, faster code */\n"
362 "___%s_really_bad_hack_to_avoid_warnings(void)\n"
364 for(li=c->nodes;li;li=g_list_next(li)) {
365 Node *node = li->data;
366 if(node->type == METHOD_NODE) {
367 Method *m = (Method *)node;
369 if(m->method == INIT_METHOD ||
370 m->method == CLASS_INIT_METHOD ||
371 m->method == OVERRIDE_METHOD)
374 /* in C++ mode we don't alias new */
375 if(for_cpp && strcmp(m->id, "new")==0)
378 out_printf(out, "\t((void (*)(void))%s)();\n", m->id);
381 out_printf(out, "\t___%s_really_bad_hack_to_avoid_warnings();\n",
384 out_printf(out, "}\n#endif /* !__GNUC__ || (__GNUC__ && __STRICT_ANSI__) */\n\n");
386 out_printf(out, "}\n\n");
390 put_variable(Variable *v, FILE *fp)
392 out_printf(fp, "\t");
393 print_type(fp, v->vtype, FALSE);
394 out_printf(fp, "%s%s;", v->id,
396 v->vtype->postfix:"");
397 if(v->scope == PROTECTED_SCOPE)
398 out_printf(fp, " /* protected */");
399 out_printf(fp, "\n");
403 put_vs_method(const Method *m)
405 if(m->method != SIGNAL_LAST_METHOD &&
406 m->method != SIGNAL_FIRST_METHOD &&
407 m->method != VIRTUAL_METHOD)
410 /* if a signal mark it as such */
411 if(m->method != VIRTUAL_METHOD)
412 print_method(outh, "\t/*signal*/", "(* ", "", ") ", "", ";\n",
413 m, FALSE, TRUE, TRUE);
415 print_method(outh, "\t", "(* ", "", ") ", "", ";\n",
416 m, FALSE, TRUE, TRUE);
420 put_pub_method(const Method *m)
422 if(m->scope != PUBLIC_SCOPE)
425 print_method(outh, "", "\t", "", "\t", "", ";\n", m, TRUE, FALSE, TRUE);
429 put_signal_macro (const Method *m, gboolean gnu)
433 if(m->method != SIGNAL_LAST_METHOD &&
434 m->method != SIGNAL_FIRST_METHOD)
437 id = g_strdup (m->id);
441 out_printf (outh, "#define %s_SIGNAL_%s(func)\t"
442 "\"%s\",GTK_SIGNAL_FUNC(func)\n",
443 macrobase, id, get_real_id (m->id));
445 out_printf (outh, "#define %s_SIGNAL_%s(func)\t"
446 "\"%s\",GTK_SIGNAL_FUNC(({",
447 macrobase, id, get_real_id (m->id));
448 print_method (outh, "", "(* ___", "", ") ", ", gpointer data ",
449 " = func; ", m, FALSE, TRUE, TRUE);
450 out_printf (outh, "___%s; }))\n", get_real_id (m->id));
457 put_signal_macros (const Class *c, gboolean gnu)
464 for (li = c->nodes; li != NULL; li = li->next) {
465 const Node *n = li->data;
466 if (n->type == METHOD_NODE)
467 put_signal_macro ((Method *)n, gnu);
473 put_prot_method(const Method *m)
475 if(m->scope != PROTECTED_SCOPE)
479 print_method(outph, "", "\t", "", "\t", "", ";\n",
480 m, FALSE, FALSE, TRUE);
482 print_method(out, "", "\t", "", "\t", "", ";\n",
483 m, FALSE, FALSE, TRUE);
487 put_priv_method_prot(Method *m)
489 if(m->method == SIGNAL_LAST_METHOD ||
490 m->method == SIGNAL_FIRST_METHOD ||
491 m->method == VIRTUAL_METHOD) {
494 "static ", "___real_", "", " ", "", ";\n",
495 m, FALSE, FALSE, TRUE);
497 /* no else, here, it might still have a private prototype, it's not
500 if((m->method == OVERRIDE_METHOD &&
503 char *s = g_strdup_printf("___%x_", (guint)m->unique_id);
504 print_method(out, "static ", s, "", " ", "",
505 no_gnu?";\n":" G_GNUC_UNUSED;\n",
506 m, FALSE, FALSE, FALSE);
508 } else if(m->scope == PRIVATE_SCOPE ||
509 m->method == INIT_METHOD ||
510 m->method == CLASS_INIT_METHOD)
511 print_method(out, "static ", "", "", " ", "",
512 no_gnu?";\n":" G_GNUC_UNUSED;\n",
513 m, FALSE, FALSE, TRUE);
517 make_func_arg(char *typename, int is_class, char *name)
524 tn = g_strconcat(typename, ":Class", NULL);
526 tn = g_strdup(typename);
528 type = new_type(tn, g_strdup("*"), NULL);
529 node = new_funcarg((Type *)type, name, NULL);
530 return g_list_prepend(NULL, node);
534 make_inits(Class *cl)
536 int got_class_init = FALSE;
537 int got_init = FALSE;
540 for(li=cl->nodes;li;li=g_list_next(li)) {
542 if(n->type == METHOD_NODE) {
543 Method *m = (Method *)n;
544 if(m->method == INIT_METHOD) {
546 error_print(GOB_ERROR, m->line_no, "init defined more then once");
548 } else if(m->method == CLASS_INIT_METHOD) {
550 error_print(GOB_ERROR, m->line_no, "class_init defined more then once");
551 got_class_init = TRUE;
555 if(!got_class_init) {
556 node = new_method(NO_SCOPE, CLASS_INIT_METHOD,
557 (Type *)new_type(g_strdup("void"),
559 NULL, NULL, NULL, g_strdup("class_init"),
560 make_func_arg(cl->otype, TRUE, g_strdup("c")),
561 NULL, NULL, NULL, 0, 0, FALSE,
563 FALSE /*bonobo_x_func*/);
564 cl->nodes = g_list_prepend(cl->nodes, node);
567 node = new_method(NO_SCOPE, INIT_METHOD,
568 (Type *)new_type(g_strdup("void"),
570 NULL, NULL, NULL, g_strdup("init"),
571 make_func_arg(cl->otype, FALSE, g_strdup("o")),
572 NULL, NULL, NULL, 0, 0, FALSE,
574 FALSE /*bonobo_x_func*/);
575 cl->nodes = g_list_prepend(cl->nodes, node);
580 find_destroy(Class *cl)
584 destroy_handler = NULL;
585 for(li=cl->nodes;li;li=g_list_next(li)) {
587 if(n->type == METHOD_NODE) {
588 Method *m = (Method *)n;
589 if(m->method == OVERRIDE_METHOD &&
590 strcmp(m->id, "destroy")==0) {
591 if(strcmp(m->otype, "Gtk:Object") != 0) {
592 error_print(GOB_ERROR, m->line_no,
593 "destroy method override "
594 "of class other then "
597 if(g_list_length(m->args) != 1) {
598 error_print(GOB_ERROR, m->line_no,
599 "destroy method override "
600 "with more then one "
611 find_finalize(Class *cl)
615 finalize_handler = NULL;
616 for(li=cl->nodes;li;li=g_list_next(li)) {
618 if(n->type == METHOD_NODE) {
619 Method *m = (Method *)n;
620 if(m->method == OVERRIDE_METHOD &&
621 strcmp(m->id, "finalize")==0) {
622 if(strcmp(m->otype, "Gtk:Object") != 0 &&
623 strcmp(m->otype, "G:Object") != 0) {
624 error_print(GOB_ERROR, m->line_no,
625 "finalize method override "
626 "of class other then "
627 "Gtk:Object (or G:Object"
630 if(g_list_length(m->args) != 1) {
631 error_print(GOB_ERROR, m->line_no,
632 "finalize method override "
633 "with more then one "
636 finalize_handler = m;
644 /* hash of method -> name of signal prototype */
645 static GHashTable *marsh = NULL;
647 /* list of methods with different signal prototypes,
648 we check this list if we can use a signal prototype of a
649 previous signal method, there are only uniques here */
650 static GList *eq_signal_methods = NULL;
652 /* compare a list of strings */
654 is_list_equal(GList *a, GList *b)
656 for(;a && b; a=a->next, b=b->next) {
657 if(strcmp(a->data, b->data)!=0) {
661 /* the the lists were different length */
668 find_same_type_signal(Method *m)
671 for(li=eq_signal_methods;li;li=li->next) {
672 Method *mm = li->data;
673 if(is_list_equal(mm->gtktypes, m->gtktypes))
680 print_signal_marsal_args_gtk1 (Method *m)
682 if(strcmp(m->gtktypes->next->data, "NONE")!=0) {
685 for(i=0, li=m->gtktypes->next;li;
686 i++, li=g_list_next(li)) {
688 out_printf(out, ",\n\t\tGTK_VALUE_%s(args[%d])",
689 (char *)li->data, i);
691 out_printf(out, ",\n\t\t(%s)"
692 "GTK_VALUE_%s(args[%d])",
693 get_cast(li->data, FALSE),
694 (char *)li->data, i);
698 out_printf(out, ",\n\t\tfunc_data);\n}\n\n");
702 add_marshal_gtk1 (Method *m, const char *mname)
704 out_printf(out, "\nstatic void\n"
705 "___marshal_%s (GtkObject * object,\n"
706 "\tGtkSignalFunc func,\n"
707 "\tgpointer func_data,\n"
711 if(strcmp(m->gtktypes->data, "NONE")==0) {
712 out_printf(out, "\t___%s rfunc;\n\n"
713 "\trfunc = (___%s)func;\n\n"
714 "\t(*rfunc)((%s *)object", mname, mname, typebase);
716 const char *retcast = get_cast(m->gtktypes->data, FALSE);
717 gboolean is_none = (strcmp(m->gtktypes->next->data, "NONE")==0);
721 "\trfunc = (___%s)func;\n\n"
722 "\tretval = GTK_RETLOC_%s(args[%d]);\n\n"
723 "\t*retval = (*rfunc)((%s *)object",
724 mname, retcast, mname,
725 (char *)m->gtktypes->data,
726 g_list_length(m->gtktypes) - (is_none ? 2 : 1),
729 print_signal_marsal_args_gtk1 (m);
733 gtk2_debool (const char *s)
735 if (strcmp (s, "BOOL") == 0)
742 print_signal_marsal_args_gtk2 (Method *m)
744 if (strcmp (m->gtktypes->next->data, "NONE") != 0) {
747 for (i = 0, li = m->gtktypes->next;
749 i++, li = li->next) {
750 char *get_func = g_strdup_printf
752 (char *)gtk2_debool (li->data));
753 g_strdown (get_func);
754 out_printf (out, ",\n\t\t(%s) "
755 "%s (param_values + %d)",
756 get_cast (li->data, FALSE),
761 out_printf (out, ",\n\t\tdata2);\n");
765 add_marshal_gtk2 (Method *m, const char *mname)
768 gboolean arglist_none;
771 ret_none = strcmp (m->gtktypes->data, "NONE") == 0;
772 arglist_none = strcmp (m->gtktypes->next->data, "NONE") == 0;
777 retcast = get_cast (m->gtktypes->data, FALSE);
779 out_printf (out, "\nstatic void\n"
780 "___marshal_%s (GClosure *closure,\n"
781 "\tGValue *return_value,\n"
782 "\tguint n_param_values,\n"
783 "\tconst GValue *param_values,\n"
784 "\tgpointer invocation_hint,\n"
785 "\tgpointer marshal_data)\n"
789 out_printf (out, "\t%s v_return;\n", retcast);
791 out_printf (out, "\tregister ___%s callback;\n"
792 "\tregister GCClosure *cc = (GCClosure*) closure;\n"
793 "\tregister gpointer data1, data2;\n\n",
796 out_printf (out, "\tg_return_if_fail (n_param_values == %d);\n\n",
797 arglist_none ? 1 : g_list_length (m->gtktypes));
800 "\tif (G_CCLOSURE_SWAP_DATA (closure)) {\n"
801 "\t\tdata1 = closure->data;\n"
802 "\t\tdata2 = g_value_peek_pointer (param_values + 0);\n"
804 "\t\tdata1 = g_value_peek_pointer (param_values + 0);\n"
805 "\t\tdata2 = closure->data;\n"
808 out_printf (out, "\tcallback = (___%s) "
809 "(marshal_data != NULL ? marshal_data : cc->callback);"
813 out_printf (out, "\tcallback ((%s *)data1", typebase);
815 out_printf (out, "\tv_return = callback ((%s *)data1",
819 print_signal_marsal_args_gtk2 (m);
822 /* FIXME: This code is so fucking ugly it hurts */
823 gboolean take_ownership =
824 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
825 strcmp ((char *)m->gtktypes->data, "BOXED") == 0);
826 char *set_func = g_strdup_printf ("g_value_set_%s%s",
827 (char *)gtk2_debool (m->gtktypes->data),
829 "_take_ownership" : "");
830 g_strdown (set_func);
832 out_printf (out, "\n\t%s (return_value, v_return);\n",
837 out_printf (out, "}\n\n");
843 add_signal_prots(Method *m)
850 if(m->method != SIGNAL_LAST_METHOD &&
851 m->method != SIGNAL_FIRST_METHOD)
855 marsh = g_hash_table_new(NULL, NULL);
857 if(strcmp(m->gtktypes->data, "NONE")==0 &&
858 strcmp(m->gtktypes->next->data, "NONE")==0)
861 /* if we already did a signal prototype just use that */
862 mm = find_same_type_signal(m);
864 s = g_hash_table_lookup(marsh, mm);
865 g_hash_table_insert(marsh, m, s);
869 s = g_strdup_printf("Sig%d", sig++);
871 g_hash_table_insert(marsh, m, s);
872 eq_signal_methods = g_list_prepend(eq_signal_methods, m);
874 /* we know that we'll know all the gtktypes (so get_cast can't fail) */
875 out_printf(out, "\ntypedef %s (*___%s) (%s *, ",
876 get_cast(m->gtktypes->data, FALSE), s, typebase);
878 if (strcmp (m->gtktypes->next->data, "NONE") != 0) {
879 for (li = m->gtktypes->next; li != NULL; li = li->next)
880 out_printf(out, "%s, ", get_cast(li->data, FALSE));
882 out_printf (out, "gpointer);\n");
885 out_printf (out, "\n#ifdef G_OBJECT_CLASS\n");
886 add_marshal_gtk2 (m, s);
887 out_printf (out, "#else /* ! G_OBJECT_CLASS */\n");
888 add_marshal_gtk1 (m, s);
889 out_printf (out, "#endif /* G_OBJECT_CLASS */\n\n");
896 out_printf(out, "\n");
898 out_printf(out, "enum {\n");
899 for(li=c->nodes;li;li=g_list_next(li)) {
901 if(n->type == METHOD_NODE) {
902 Method *m = (Method *)n;
903 if(m->method == SIGNAL_LAST_METHOD ||
904 m->method == SIGNAL_FIRST_METHOD) {
905 char *s = g_strdup(get_real_id(m->id));
907 out_printf(out, "\t%s_SIGNAL,\n", s);
912 out_printf(out, "\tLAST_SIGNAL\n};\n\n");
914 if(set_arguments > 0 || get_arguments > 0) {
915 out_printf(out, "enum {\n\tARG_0");
916 for(li=c->nodes;li;li=g_list_next(li)) {
918 if(n->type == ARGUMENT_NODE) {
919 Argument *a = (Argument *)n;
920 char *s = g_strdup(a->name);
922 out_printf(out, ",\n\tARG_%s", s);
926 out_printf(out, "\n};\n\n");
931 "static guint object_signals[LAST_SIGNAL] = {0};\n\n");
933 out_printf(out, "/* pointer to the class of our parent */\n");
934 out_printf(out, "static %sClass *parent_class = NULL;\n\n", ptypebase);
940 char *chunk_size = ((Class*)class)->chunk_size;
944 "%s_get_type (void)\n"
946 "\tstatic GtkType type = 0;\n\n"
947 "\tif (type == 0) {\n"
948 "\t\tstatic const GtkTypeInfo info = {\n"
950 "\t\t\tsizeof (%s),\n"
951 "\t\t\tsizeof (%sClass),\n"
952 "\t\t\t(GtkClassInitFunc) %s_class_init,\n"
953 "\t\t\t(GtkObjectInitFunc) %s_init,\n"
954 "\t\t\t/* reserved_1 */ NULL,\n"
955 "\t\t\t/* reserved_2 */ NULL,\n"
956 "\t\t\t(GtkClassInitFunc) NULL\n"
958 "\t\ttype = gtk_type_unique (%s_get_type(), &info);\n",
959 funcbase, typebase, typebase, typebase,
960 funcbase, funcbase, pfuncbase);
964 "\t\tgtk_type_set_chunk_alloc(type, %s);\n"
966 chunk_size, chunk_size);
975 add_bonobo_x_get_type (void)
977 char *chunk_size = ((Class*)class)->chunk_size;
981 "%s_get_type (void)\n"
983 "\tstatic GtkType type = 0;\n\n"
984 "\tif (type == 0) {\n"
985 "\t\tstatic const GtkTypeInfo info = {\n"
987 "\t\t\tsizeof (%s),\n"
988 "\t\t\tsizeof (%sClass),\n"
989 "\t\t\t(GtkClassInitFunc) %s_class_init,\n"
990 "\t\t\t(GtkObjectInitFunc) %s_init,\n"
991 "\t\t\t/* reserved_1 */ NULL,\n"
992 "\t\t\t/* reserved_2 */ NULL,\n"
993 "\t\t\t(GtkClassInitFunc) NULL\n"
995 "\t\ttype = bonobo_x_type_unique\n"
996 "\t\t\t(%s_get_type (),\n"
997 "\t\t\tPOA_%s__init, NULL,\n"
998 "\t\t\tGTK_STRUCT_OFFSET (%sClass, _epv),\n"
1000 funcbase, typebase, typebase, typebase,
1001 funcbase, funcbase, pfuncbase,
1002 ((Class*)class)->bonobo_x_class,
1007 "\t\tgtk_type_set_chunk_alloc(type, %s);\n"
1009 chunk_size, chunk_size);
1018 add_overrides(Class *c, const char *oname, gboolean did_base_obj)
1024 done = g_hash_table_new(g_str_hash, g_str_equal);
1026 s = g_strdup("GtkObject"); /* This was already done */
1027 g_hash_table_insert(done, s, s);
1028 s = g_strdup("GObject"); /* This was probably already done as well (if using Gtk/Glib 1.3/2.0) */
1029 g_hash_table_insert(done, s, s);
1031 for(li=c->nodes; li; li=g_list_next(li)) {
1034 Method *m = (Method *)n;
1035 if(n->type != METHOD_NODE ||
1036 m->method != OVERRIDE_METHOD)
1039 s = remove_sep(m->otype);
1041 if(g_hash_table_lookup(done, s)) {
1045 g_hash_table_insert(done, s, s);
1047 f = replace_sep(m->otype, '_');
1050 out_printf(out, "\t%sClass *%s_class = (%sClass *)%s;\n",
1055 g_hash_table_foreach(done, (GHFunc)g_free, NULL);
1056 g_hash_table_destroy(done);
1060 make_run_signal_flags(Method *m, gboolean last)
1074 gs = g_string_new(NULL);
1077 g_string_assign(gs, "GTK_RUN_LAST");
1079 g_string_assign(gs, "GTK_RUN_FIRST");
1081 if(m->scope == PUBLIC_SCOPE)
1082 g_string_append(gs, " | GTK_RUN_ACTION");
1084 for(li = m->flags; li; li = li->next) {
1085 char *flag = li->data;
1087 for(i=0;flags[i];i++) {
1088 if(strcmp(flags[i], flag)==0)
1091 /* if we haven't found it in our list */
1093 error_printf(GOB_WARN, m->line_no,
1094 "Unknown flag '%s' used, "
1095 "perhaps it was misspelled",
1098 g_string_sprintfa(gs, " | GTK_RUN_%s", flag);
1102 char *ret = gs->str;
1103 g_string_free(gs, FALSE);
1110 add_signals(Class *c)
1114 out_printf(out, "\n");
1115 for(li=c->nodes;li;li=g_list_next(li)) {
1117 char *mar, *sig, *flags;
1118 gboolean is_none, last = FALSE;
1119 Method *m = (Method *)n;
1121 if(n->type != METHOD_NODE ||
1122 (m->method != SIGNAL_FIRST_METHOD &&
1123 m->method != SIGNAL_LAST_METHOD))
1126 if(m->method == SIGNAL_FIRST_METHOD)
1131 if(g_hash_table_lookup(marsh, m))
1132 mar = g_strconcat("___marshal_",
1133 (char *)g_hash_table_lookup(marsh, m),
1136 mar = g_strdup("gtk_signal_default_marshaller");
1138 is_none = (strcmp(m->gtktypes->next->data, "NONE")==0);
1140 sig = g_strdup(get_real_id(m->id));
1142 flags = make_run_signal_flags(m, last);
1143 out_printf(out, "\tobject_signals[%s_SIGNAL] =\n"
1144 "\t\tgtk_signal_new (\"%s\",\n"
1145 "\t\t\t(GtkSignalRunType)(%s),\n"
1146 "\t\t\tGTK_CLASS_TYPE(gtk_object_class),\n"
1147 "\t\t\tGTK_SIGNAL_OFFSET (%sClass, %s),\n"
1149 "\t\t\tGTK_TYPE_%s, %d",
1150 sig, get_real_id(m->id),
1152 typebase, get_real_id(m->id), mar,
1153 (char *)m->gtktypes->data,
1154 is_none ? 0 : g_list_length(m->gtktypes->next));
1161 for(l = m->gtktypes->next; l != NULL; l = l->next)
1162 out_printf(out, ",\n\t\t\tGTK_TYPE_%s",
1166 out_printf(out, ");\n");
1168 if(strcmp(m->gtktypes->data, "NONE") != 0 ||
1172 out_printf(out, "\tif(");
1173 if(strcmp(m->gtktypes->data, "NONE") != 0) {
1174 out_printf(out, "%s sizeof(", sep);
1175 print_type(out, m->mtype, FALSE);
1176 out_printf(out, "%s",
1178 m->mtype->postfix : "");
1179 out_printf(out, ") != sizeof(%s)",
1180 get_cast(m->gtktypes->data, FALSE));
1185 for(al = m->args->next, gl = m->gtktypes->next;
1186 al != NULL && gl != NULL;
1187 al = al->next, gl = gl->next) {
1188 FuncArg *arg = al->data;
1189 char *gtkarg = gl->data;
1191 out_printf(out, "%ssizeof(", sep);
1192 print_type(out, arg->atype, FALSE);
1193 out_printf(out, "%s",
1194 arg->atype->postfix ?
1195 arg->atype->postfix : "");
1196 out_printf(out, ") != sizeof(%s)",
1197 get_cast(gtkarg, FALSE));
1201 out_printf(out, ") {\n"
1202 "\t\tg_error(\"%s line %d: Type mismatch "
1203 "of \\\"%s\\\" signal signature\");\n"
1205 filename, m->line_no, get_real_id(m->id));
1209 out_printf (out, "#ifndef G_OBJECT_CLASS\n");
1210 out_printf (out, "\tgtk_object_class_add_signals (gtk_object_class,\n"
1211 "\t\tobject_signals, LAST_SIGNAL);\n");
1212 out_printf (out, "#endif /* ! G_OBJECT_CLASS */\n\n");
1216 set_def_handlers(Class *c, const char *oname)
1219 gboolean set_line = FALSE;
1221 out_printf(out, "\n");
1222 for(li = c->nodes; li; li = g_list_next(li)) {
1224 Method *m = (Method *)n;
1226 if(n->type != METHOD_NODE ||
1227 (m->method != SIGNAL_FIRST_METHOD &&
1228 m->method != SIGNAL_LAST_METHOD &&
1229 m->method != VIRTUAL_METHOD &&
1230 m->method != OVERRIDE_METHOD))
1233 if(m->line_no > 0 && m->cbuf) {
1234 out_addline_infile(out, m->line_no);
1236 } else if(set_line) {
1237 out_addline_outfile(out);
1242 if(m->method == OVERRIDE_METHOD) {
1244 s = replace_sep(m->otype, '_');
1249 strcmp(get_real_id(m->id), "destroy") == 0)
1250 out_printf(out, "\tgtk_object_class->destroy "
1252 else if(need_finalize &&
1254 strcmp(get_real_id(m->id), "finalize") == 0)
1256 "#ifdef G_OBJECT_CLASS\n"
1257 "\tg_object_class->finalize = ___finalize;\n"
1258 "#else /* !G_OBJECT_CLASS */\n"
1259 "\tgtk_object_class->finalize = ___finalize;\n"
1260 "#endif /* G_OBJECT_CLASS */\n");
1263 "\t%s_class->%s = ___%x_%s_%s;\n",
1264 s, get_real_id(m->id), (guint)m->unique_id,
1265 funcbase, get_real_id(m->id));
1267 out_printf(out, "\t%s_class->%s = NULL;\n",
1268 s, get_real_id(m->id));
1271 out_printf(out, "\t%s->%s = ___real_%s_%s;\n",
1272 oname, get_real_id(m->id),
1273 funcbase, get_real_id(m->id));
1275 out_printf(out, "\t%s->%s = NULL;\n",
1276 oname, get_real_id(m->id));
1280 out_addline_outfile(out);
1284 make_arguments(Class *c)
1287 char *argflags[] = {
1295 out_printf(out, "\n");
1296 for(li=c->nodes;li;li=g_list_next(li)) {
1302 if(n->type != ARGUMENT_NODE)
1307 if(a->get && a->set)
1308 flags = g_string_new("GTK_ARG_READWRITE");
1310 flags = g_string_new("GTK_ARG_READABLE");
1312 flags = g_string_new("GTK_ARG_WRITABLE");
1314 g_assert(a->get || a->set);
1316 for(l=a->flags;l;l=g_list_next(l)) {
1317 char *flag = l->data;
1319 if(strcmp(flag, "READWRITE")==0 ||
1320 strcmp(flag, "READABLE")==0 ||
1321 strcmp(flag, "WRITABLE")==0) {
1322 error_print(GOB_WARN, a->line_no,
1323 "READWRITE, READABLE and "
1324 "WRITABLE argument flags are "
1325 "set automatically");
1328 for(i = 0; argflags[i]; i++) {
1329 if(strcmp(argflags[i], flag)==0)
1332 /* if we haven't found it in our list */
1333 if( ! argflags[i]) {
1334 error_printf(GOB_WARN, a->line_no,
1335 "Unknown flag '%s' used, "
1336 "perhaps it was misspelled", flag);
1338 g_string_sprintfa(flags, " | GTK_ARG_%s", flag);
1341 s = g_strdup(a->name);
1343 out_printf(out, "\tgtk_object_add_arg_type(\"%s::%s\",\n"
1344 "\t\tGTK_TYPE_%s,\n"
1347 typebase, a->name, a->gtktype, flags->str, s);
1349 g_string_free(flags, TRUE);
1352 out_printf(out, "\n");
1353 if(get_arguments > 0)
1354 out_printf(out, "\tgtk_object_class->get_arg = ___object_get_arg;\n");
1355 if(set_arguments > 0)
1356 out_printf(out, "\tgtk_object_class->set_arg = ___object_set_arg;\n");
1360 print_initializer(Method *m, Variable *v)
1364 if(v->initializer == NULL)
1367 if(v->scope == PRIVATE_SCOPE)
1368 root = g_strconcat(((FuncArg *)m->args->data)->name,
1371 root = g_strdup(((FuncArg *)m->args->data)->name);
1373 if(v->initializer_line > 0)
1374 out_addline_infile(out, v->initializer_line);
1376 out_printf(out, "\t%s->%s = %s;\n",
1377 root, v->id, v->initializer);
1379 if(v->initializer_line > 0)
1380 out_addline_outfile(out);
1386 print_destructor(Variable *v)
1390 if(v->destructor == NULL)
1393 if(v->scope == PRIVATE_SCOPE)
1394 root = "self->_priv";
1398 if(v->destructor_simple) {
1399 if(v->destructor_line > 0)
1400 out_addline_infile(out, v->destructor_line);
1402 out_printf(out, "\tif(%s->%s) { "
1403 "((*(void (*)(void *))%s)) (%s->%s); "
1404 "%s->%s = NULL; }\n",
1405 root, v->id, v->destructor, root, v->id,
1408 if(v->destructor_line > 0)
1409 out_addline_outfile(out);
1411 out_printf(out, "#define VAR (%s->%s)\n", root, v->id);
1412 out_printf(out, "\t{\n");
1413 if(v->destructor_line > 0)
1414 out_addline_infile(out, v->destructor_line);
1416 out_printf(out, "\t%s}\n", v->destructor);
1418 if(v->destructor_line > 0)
1419 out_addline_outfile(out);
1420 out_printf(out, "\tmemset(&VAR, 0, sizeof(VAR));\n");
1421 out_printf(out, "#undef VAR\n");
1426 add_destroy(Class *c)
1428 out_printf(out, "\nstatic void\n"
1429 "___destroy(GtkObject *obj_self)\n"
1432 "#define __GOB_FUNCTION__ \"%s::destroy\"\n",
1435 if(destructors > 0) {
1436 out_printf(out, "\t%s *self = %s (obj_self);\n",
1437 typebase, macrobase);
1440 if(destroy_handler) {
1441 /* so we get possible bad argument warning */
1442 if(destroy_handler->line_no > 0)
1443 out_addline_infile(out, destroy_handler->line_no);
1444 out_printf(out, "\t___%x_%s_destroy(obj_self);\n",
1445 (guint)destroy_handler->unique_id, funcbase);
1446 if(destroy_handler->line_no > 0)
1447 out_addline_outfile(out);
1450 "\tif(GTK_OBJECT_CLASS(parent_class)->destroy) \\\n"
1451 "\t\t(* GTK_OBJECT_CLASS(parent_class)->destroy)(obj_self);\n");
1454 if(destructors > 0) {
1456 for(li = ((Class *)class)->nodes;
1460 Variable *v = (Variable *)n;
1461 if(n->type == VARIABLE_NODE &&
1462 v->scope != CLASS_SCOPE)
1463 print_destructor(v);
1467 out_printf(out, "\treturn;\n");
1469 out_printf(out, "\tself = NULL;\n");
1470 out_printf(out, "}\n"
1471 "#undef __GOB_FUNCTION__\n\n");
1475 add_finalize(Class *c)
1477 /* Sort of a hack to make it work with gtk+ 1.3/2.0 */
1479 "\n#ifdef G_OBJECT_CLASS\n"
1481 "___finalize(GObject *obj_self)\n"
1482 "#else /* !G_OBJECT_CLASS */\n"
1484 "___finalize(GtkObject *obj_self)\n"
1485 "#endif /* G_OBJECT_CLASS */\n"
1488 "#define __GOB_FUNCTION__ \"%s::finalize\"\n",
1492 out_printf(out, "\t%s *self = %s (obj_self);\n",
1493 typebase, macrobase);
1494 out_printf(out, "\tgpointer priv = self->_priv;\n");
1497 if(finalize_handler) {
1498 /* so we get possible bad argument warning */
1499 if(finalize_handler->line_no > 0)
1500 out_addline_infile(out, finalize_handler->line_no);
1501 out_printf(out, "\t___%x_%s_finalize(obj_self);\n",
1502 (guint)finalize_handler->unique_id, funcbase);
1503 if(finalize_handler->line_no > 0)
1504 out_addline_outfile(out);
1506 /* Sort of a hack to make it work with gtk+ 1.3/2.0 */
1508 "#ifdef G_OBJECT_CLASS\n"
1509 "\tif(G_OBJECT_CLASS(parent_class)->finalize) \\\n"
1510 "\t\t(* G_OBJECT_CLASS(parent_class)->finalize)(obj_self);\n"
1511 "#else /* !G_OBJECT_CLASS */\n"
1512 "\tif(GTK_OBJECT_CLASS(parent_class)->finalize) \\\n"
1513 "\t\t(* GTK_OBJECT_CLASS(parent_class)->finalize)(obj_self);\n"
1514 "#endif /* G_OBJECT_CLASS */\n");
1518 out_printf(out, "\tg_free(priv);\n");
1521 out_printf(out, "}\n"
1522 "#undef __GOB_FUNCTION__\n\n");
1526 make_bonobo_x_epv (Class *c, const char *classname)
1529 gboolean added_line = FALSE;
1531 for (li = c->nodes; li != NULL; li = li->next) {
1533 Method *m = (Method *)n;
1534 if(n->type != METHOD_NODE ||
1535 m->method == OVERRIDE_METHOD)
1538 if (m->bonobo_x_func) {
1539 if(m->line_no > 0) {
1540 out_addline_infile(out, m->line_no);
1542 } else if (m->line_no == 0 &&
1544 out_addline_outfile(out);
1547 out_printf (out, "\t%s->_epv.%s = %s;\n",
1548 classname, m->id, m->id);
1552 out_addline_outfile(out);
1559 for(li=c->nodes;li;li=g_list_next(li)) {
1563 gboolean add_unused_class = FALSE;
1565 if(n->type != METHOD_NODE)
1568 if(m->method == INIT_METHOD) {
1570 out_addline_infile(out, m->line_no);
1571 print_method(out, "static ", "\n", "", " ", "", "\n",
1572 m, FALSE, FALSE, TRUE);
1574 out_addline_outfile(out);
1575 out_printf(out, "{\n"
1576 "#define __GOB_FUNCTION__ \"%s::init\"\n",
1579 out_printf(out, "\t%s->_priv = "
1580 "g_new0 (%sPrivate, 1);\n",
1581 ((FuncArg *)m->args->data)->name,
1583 } else if(always_private_struct) {
1584 out_printf(out, "\t%s->_priv = NULL;\n",
1585 ((FuncArg *)m->args->data)->name);
1587 if(initializers > 0) {
1589 for(li = ((Class *)class)->nodes;
1593 Variable *v = (Variable *)n;
1594 if(n->type != VARIABLE_NODE ||
1595 v->scope == CLASS_SCOPE)
1597 print_initializer(m, v);
1600 } else if(m->method == CLASS_INIT_METHOD) {
1601 gboolean did_base_obj = FALSE;
1604 out_addline_infile(out, m->line_no);
1605 print_method(out, "static ", "\n", "", " ", "", "\n",
1606 m, FALSE, FALSE, TRUE);
1608 out_addline_outfile(out);
1609 out_printf(out, "{\n"
1610 "#define __GOB_FUNCTION__ \"%s::class_init\"\n",
1613 set_arguments > 0 ||
1614 get_arguments > 0 ||
1617 add_unused_class = TRUE;
1619 "\tGtkObjectClass *"
1620 "gtk_object_class = "
1621 "(GtkObjectClass*) %s;\n",
1622 ((FuncArg *)m->args->data)->name);
1624 "#ifdef G_OBJECT_CLASS\n"
1627 "(GObjectClass*) %s;\n"
1628 "#endif /* G_OBJECT_CLASS */\n",
1629 ((FuncArg *)m->args->data)->name);
1630 did_base_obj = TRUE;
1635 ((FuncArg *)m->args->data)->name,
1638 if(initializers > 0) {
1640 for(li = ((Class *)class)->nodes;
1644 Variable *v = (Variable *)n;
1645 if(n->type == VARIABLE_NODE &&
1646 v->scope == CLASS_SCOPE)
1647 print_initializer(m, v);
1651 out_printf(out, "\n\tparent_class = ");
1653 out_printf(out, "(%sClass *)", ptypebase);
1654 out_printf(out, "gtk_type_class (%s_get_type ());\n",
1660 set_def_handlers(c, ((FuncArg *)m->args->data)->name);
1662 /* if there are no handlers for these things, we
1663 * need to set them up here */
1664 if(need_destroy && !destroy_handler)
1665 out_printf(out, "\tgtk_object_class->destroy "
1667 if(need_finalize && !finalize_handler)
1669 "#ifdef G_OBJECT_CLASS\n"
1670 "\tg_object_class->finalize = ___finalize;\n"
1671 "#else /* !G_OBJECT_CLASS */\n"
1672 "\tgtk_object_class->finalize = ___finalize;\n"
1673 "#endif /* G_OBJECT_CLASS */\n");
1675 if(get_arguments > 0 || set_arguments > 0)
1678 if (c->bonobo_x_class != NULL) {
1679 make_bonobo_x_epv (c, ((FuncArg *)m->args->data)->name);
1685 out_printf(out, " {\n");
1686 out_addline_infile(out, m->ccode_line);
1687 out_printf(out, "%s\n", m->cbuf);
1688 out_addline_outfile(out);
1689 out_printf(out, " }\n");
1691 out_printf(out, "\treturn;\n");
1694 ((FuncArg *)m->args->data)->name);
1695 if(add_unused_class) {
1697 "\tgtk_object_class = NULL;\n"
1698 "#ifdef G_OBJECT_CLASS\n"
1699 "\tg_object_class = NULL;\n"
1700 "#endif /* G_OBJECT_CLASS */\n");
1702 out_printf(out, "}\n"
1703 "#undef __GOB_FUNCTION__\n");
1708 add_getset_arg(Class *c, gboolean is_set)
1711 out_printf(out, "\nstatic void\n"
1712 "___object_%s_arg (GtkObject *object,\n"
1715 "#define __GOB_FUNCTION__ \"%s::%s_arg\"\n"
1718 "\tself = %s (object);\n\n"
1719 "\tswitch (arg_id) {\n",
1720 is_set ? "set" : "get",
1721 c->otype, is_set ? "set" : "get",
1722 typebase, macrobase);
1724 for(li=c->nodes;li;li=g_list_next(li)) {
1730 if(n->type != ARGUMENT_NODE)
1735 line_no = a->set_line;
1738 line_no = a->get_line;
1742 s = g_strdup(a->name);
1744 out_printf(out, "\tcase ARG_%s:\n", s);
1745 if(is_set && a->atype) {
1746 char *cast = get_type(a->atype, TRUE);
1747 if(no_gnu || for_cpp) {
1748 out_printf(out, "#define ARG "
1749 "((%s)GTK_VALUE_%s(*arg))\n",
1752 out_printf(out, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
1753 if(strcmp(a->gtktype, "OBJECT")==0) {
1754 out_printf(out, "#define ARG "
1756 "GTK_VALUE_POINTER(*arg); "
1760 out_printf(out, "#define ARG "
1762 "GTK_VALUE_%s(*arg); "
1766 out_printf(out, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
1767 out_printf(out, "#define ARG "
1768 "((%s)GTK_VALUE_%s(*arg))\n",
1770 out_printf(out, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n");
1772 out_printf(out, "\t\t{\n");
1774 } else if(!is_set && strcmp(a->gtktype, "OBJECT")==0) {
1776 "#define ARG (GTK_VALUE_POINTER(*arg))\n"
1780 "#define ARG (GTK_VALUE_%s(*arg))\n"
1786 out_addline_infile(out, line_no);
1787 out_printf(out, "%s\n", cbuf);
1789 out_addline_outfile(out);
1790 out_printf(out, "\t\t}\n\t\tbreak;\n"
1793 out_printf(out, "\tdefault:\n\t\tbreak;\n\t}\n"
1794 "\treturn;\n\tself = NULL;\n\targ = NULL;\n}\n"
1795 "#undef __GOB_FUNCTION__\n");
1799 print_checks(Method *m, FuncArg *fa)
1803 gboolean checked_null = FALSE;
1804 is_void = (strcmp(m->mtype->name, "void")==0 &&
1805 m->mtype->pointer == NULL);
1807 for(li = fa->checks; li; li = g_list_next(li)) {
1808 Check *ch = li->data;
1810 /* point to the method prot in .gob for failed checks */
1812 out_addline_infile(out, m->line_no);
1814 out_printf(out, "\tg_return_if_fail (");
1816 out_printf(out, "\tg_return_val_if_fail (");
1817 switch(ch->chtype) {
1819 out_printf(out, "%s != NULL", fa->name);
1820 checked_null = TRUE;
1823 s = make_pre_macro(fa->atype->name, "IS");
1825 out_printf(out, "%s (%s)", s, fa->name);
1827 /* if not check null, null may be valid */
1828 out_printf(out, "!(%s) || %s (%s)", fa->name,
1833 out_printf(out, "%s < %s", fa->name, ch->number);
1836 out_printf(out, "%s > %s", fa->name, ch->number);
1839 out_printf(out, "%s <= %s", fa->name, ch->number);
1842 out_printf(out, "%s >= %s", fa->name, ch->number);
1845 out_printf(out, "%s == %s", fa->name, ch->number);
1848 out_printf(out, "%s != %s", fa->name, ch->number);
1852 out_printf(out, ");\n");
1854 out_printf(out, ", (");
1855 print_type(out, m->mtype, TRUE);
1856 out_printf(out, ")%s);\n",
1857 m->onerror?m->onerror:"0");
1863 print_preconditions(Method *m)
1867 for(li=m->args;li;li=g_list_next(li)) {
1868 FuncArg *fa = li->data;
1870 print_checks(m, fa);
1873 out_addline_outfile(out);
1877 print_method_body(Method *m, int pre)
1880 out_addline_outfile(out);
1881 out_printf(out, "{\n"
1882 "#define __GOB_FUNCTION__ \"%s::%s\"\n",
1883 ((Class *)class)->otype,
1884 get_real_id(m->id));
1886 print_preconditions(m);
1888 /* Note: the trailing }'s are on one line, this is so
1889 that we get the no return warning correctly and point to
1890 the correct line in the .gob file, yes this is slightly
1891 ugly in the .c file, but that is not supposed to be
1892 human readable anyway. */
1894 out_printf(out, "{\n");
1896 out_addline_infile(out, m->ccode_line);
1897 out_printf(out, "\t%s}", m->cbuf);
1900 /* Note, there is no \n between the last } and this } so that
1901 * errors/warnings reported on the end of the body get pointed to the
1902 * right line in the .gob source */
1903 out_printf(out, "}\n");
1906 out_addline_outfile(out);
1907 out_printf(out, "#undef __GOB_FUNCTION__\n");
1911 put_signal_args(Method *m)
1915 for(ali = m->gtktypes->next, li=m->args->next;
1917 li=li->next, ali=ali->next) {
1918 FuncArg *fa = li->data;
1919 const char *cast = get_cast(ali->data, FALSE);
1920 /* we should have already proved before that
1921 the we know all the types */
1924 out_printf(out, ",\n\t\t(%s)%s", cast,
1930 get_arg_names_for_macro(Method *m)
1934 GString *gs = g_string_new(NULL);
1936 for(li=m->args;li;li=g_list_next(li)) {
1937 FuncArg *arg = li->data;
1938 g_string_sprintfa(gs, "%s___%s", p, arg->name);
1942 g_string_free(gs, FALSE);
1947 put_method(Method *m)
1949 char *s, *args, *doc;
1951 is_void = (strcmp(m->mtype->name, "void")==0 &&
1952 m->mtype->pointer == NULL);
1953 out_printf(out, "\n");
1954 if(m->method != OVERRIDE_METHOD) {
1955 doc = get_gtk_doc(m->id);
1957 out_printf(out, "%s", doc);
1962 case REGULAR_METHOD:
1964 out_addline_infile(out, m->line_no);
1965 if(m->scope == PRIVATE_SCOPE)
1966 print_method(out, "static ", "\n", "", " ", "", "\n",
1967 m, FALSE, FALSE, TRUE);
1968 else /* PUBLIC, PROTECTED */
1969 print_method(out, "", "\n", "", " ", "", "\n",
1970 m, FALSE, FALSE, TRUE);
1971 print_method_body(m, TRUE);
1972 /* the outfile line was added above */
1974 case SIGNAL_FIRST_METHOD:
1975 case SIGNAL_LAST_METHOD:
1977 out_addline_infile(out, m->line_no);
1978 if(m->scope == PRIVATE_SCOPE)
1979 print_method(out, "static ", "\n", "", " ", "", "\n",
1980 m, FALSE, FALSE, TRUE);
1981 else /* PUBLIC, PROTECTED */
1982 print_method(out, "", "\n", "", " ", "", "\n",
1983 m, FALSE, FALSE, TRUE);
1984 out_addline_outfile(out);
1985 out_printf(out, "{\n");
1986 s = g_strdup(get_real_id(m->id));
1988 if(strcmp(m->mtype->name, "void") == 0 &&
1989 m->mtype->pointer == NULL) {
1990 print_preconditions(m);
1991 if(((FuncArg *)m->args->data)->name)
1992 out_printf(out, "\tgtk_signal_emit (GTK_OBJECT (%s),\n"
1993 "\t\tobject_signals[%s_SIGNAL]",
1994 ((FuncArg *)m->args->data)->name, s);
1996 out_printf(out, ");\n}\n");
1998 out_printf(out, "\t");
1999 print_type(out, m->mtype, TRUE);
2000 out_printf(out, "return_val = (");
2001 print_type(out, m->mtype, TRUE);
2003 out_printf(out, ")(%s);\n", m->defreturn);
2005 out_printf(out, ")(%s);\n", m->onerror);
2007 out_printf(out, ")(0);\n");
2008 print_preconditions(m);
2009 out_printf(out, "\tgtk_signal_emit (GTK_OBJECT (%s),\n"
2010 "\t\tobject_signals[%s_SIGNAL]",
2011 ((FuncArg *)m->args->data)->name, s);
2013 out_printf(out, ",\n\t\t&return_val);\n"
2014 "\treturn return_val;\n}\n");
2020 out_addline_infile(out, m->line_no);
2021 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
2022 m, FALSE, FALSE, TRUE);
2023 print_method_body(m, FALSE);
2024 /* the outfile line was added above */
2026 case VIRTUAL_METHOD:
2028 out_addline_infile(out, m->line_no);
2029 if(m->scope==PRIVATE_SCOPE)
2030 print_method(out, "static ", "\n", "", " ", "", "\n",
2031 m, FALSE, FALSE, TRUE);
2032 else /* PUBLIC, PROTECTED */
2033 print_method(out, "", "\n", "", " ", "", "\n",
2034 m, FALSE, FALSE, TRUE);
2035 out_addline_outfile(out);
2036 out_printf(out, "{\n"
2037 "\t%sClass *klass;\n", typebase);
2038 print_preconditions(m);
2039 out_printf(out, "\tklass = %s_GET_CLASS(%s);\n\n"
2040 "\tif(klass->%s)\n",
2041 macrobase, ((FuncArg *)m->args->data)->name,
2042 get_real_id(m->id));
2043 if(strcmp(m->mtype->name, "void") == 0 &&
2044 m->mtype->pointer == NULL) {
2046 out_printf(out, "\t\t(*klass->%s)(%s",
2048 ((FuncArg *)m->args->data)->name);
2049 for(li=m->args->next;li;li=g_list_next(li)) {
2050 FuncArg *fa = li->data;
2051 out_printf(out, ",%s", fa->name);
2053 out_printf(out, ");\n}\n");
2056 out_printf(out, "\t\treturn (*klass->%s)(%s",
2058 ((FuncArg *)m->args->data)->name);
2059 for(li=m->args->next;li;li=g_list_next(li)) {
2060 FuncArg *fa = li->data;
2061 out_printf(out, ",%s", fa->name);
2063 out_printf(out, ");\n"
2066 print_type(out, m->mtype, TRUE);
2068 out_printf(out, ")(%s);\n}\n", m->defreturn);
2070 out_printf(out, ")(%s);\n}\n", m->onerror);
2072 out_printf(out, ")(0);\n}\n");
2078 out_addline_infile(out, m->line_no);
2079 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
2080 m, FALSE, FALSE, TRUE);
2081 print_method_body(m, FALSE);
2082 /* the outfile line was added above */
2084 case OVERRIDE_METHOD:
2088 out_addline_infile(out, m->line_no);
2089 s = g_strdup_printf("\n___%x_", (guint)m->unique_id);
2090 print_method(out, "static ", s, "", " ", "", "\n",
2091 m, FALSE, FALSE, FALSE);
2093 out_addline_outfile(out);
2094 s = replace_sep(m->otype, '_');
2096 args = get_arg_names_for_macro(m);
2098 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
2099 "\t{ if(%s_CLASS(parent_class)->%s) \\\n"
2100 "\t\t(* %s_CLASS(parent_class)->%s)(%s); }\n",
2101 args, s, get_real_id(m->id), s, get_real_id(m->id), args);
2103 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
2104 "\t((%s_CLASS(parent_class)->%s)? \\\n"
2105 "\t\t(* %s_CLASS(parent_class)->%s)(%s): \\\n"
2107 args, s, get_real_id(m->id), s, get_real_id(m->id), args);
2108 out_printf(out, "(");
2109 print_type(out, m->mtype, TRUE);
2110 out_printf(out, ")%s))\n",
2111 m->onerror?m->onerror:"0");
2115 print_method_body(m, TRUE);
2116 /* the outfile line was added above */
2117 out_printf(out, "#undef PARENT_HANDLER\n");
2127 char *outfile, *outfileh, *outfileph;
2130 outfile = g_strconcat(filebase, ".c", NULL);
2132 outfile = g_strconcat(filebase, ".cc", NULL);
2133 if(no_touch_headers)
2134 outfileh = g_strconcat("#gob#", filebase, ".h#gob#", NULL);
2136 outfileh = g_strconcat(filebase, ".h", NULL);
2138 if((privates > 0 || protecteds > 0 ||
2139 private_header == PRIVATE_HEADER_ALWAYS) &&
2140 private_header != PRIVATE_HEADER_NEVER)
2141 outfileph = g_strconcat(filebase, "-private.h", NULL);
2147 devnull = fopen("/dev/null", "w");
2149 g_error("Cannot open null device");
2155 out = fopen(outfile, "w");
2157 g_error("Cannot open outfile: %s", outfile);
2159 outh = fopen(outfileh, "w");
2161 g_error("Cannot open outfile: %s", outfileh);
2163 outph = fopen(outfileph, "w");
2165 g_error("Cannot open outfile: %s", outfileh);
2171 put_argument_nongnu_wrappers(Class *c)
2175 if(get_arguments < 0 && set_arguments < 0)
2178 for(li=c->nodes;li;li=g_list_next(li)) {
2180 Argument *a = (Argument *)n;
2184 if(n->type != ARGUMENT_NODE)
2187 aname = g_strdup(a->name);
2191 cast = get_type(a->atype, TRUE);
2193 cast = g_strdup(get_cast(a->gtktype, TRUE));
2197 out_printf(outh, "#define %s_ARG_%s(arg) \t"
2198 "\"%s\",(%s)(arg)\n",
2199 macrobase, aname, a->name, cast);
2201 out_printf(outh, "#define %s_GET_ARG_%s(arg)\t"
2202 "\"%s\",(%s*)(arg)\n",
2203 macrobase, aname, a->name, cast);
2206 out_printf(outh, "#define %s_ARG_%s(arg) \t"
2208 macrobase, aname, a->name);
2210 out_printf(outh, "#define %s_GET_ARG_%s(arg)\t"
2212 macrobase, aname, a->name);
2220 put_argument_gnu_wrappers(Class *c)
2224 if(get_arguments < 0 && set_arguments < 0)
2227 for(li=c->nodes;li;li=g_list_next(li)) {
2229 Argument *a = (Argument *)n;
2232 if(n->type != ARGUMENT_NODE)
2234 s = g_strdup(a->name);
2237 cast = get_type(a->atype, TRUE);
2239 cast = g_strdup(get_cast(a->gtktype, TRUE));
2242 out_printf(outh, "#define %s_ARG_%s(arg) \t"
2243 "\"%s\",({%sz = (arg); z;})\n",
2244 macrobase, s, a->name, cast);
2246 out_printf(outh, "#define %s_GET_ARG_%s(arg)\t"
2247 "\"%s\",({%s*z = (arg); z;})\n",
2248 macrobase, s, a->name, cast);
2251 out_printf(outh, "#define %s_ARG_%s(arg) \t"
2253 macrobase, s, a->name);
2255 out_printf(outh, "#define %s_GET_ARG_%s(arg)\t"
2257 macrobase, s, a->name);
2265 print_ccode_block(CCode *cc)
2268 switch(cc->cctype) {
2270 /* HT code is printed exactly like normal header
2271 code but is printed before */
2274 out_printf(fp, "\n");
2277 /* AT code is printed exactly like normal 'all'
2278 code but is printed before */
2281 out_printf(outph, "\n");
2282 out_printf(outph, "%s\n", cc->cbuf);
2283 out_addline_infile(outph, cc->line_no);
2284 out_addline_outfile(outph);
2286 out_printf(outh, "\n");
2287 out_printf(outh, "%s\n", cc->cbuf);
2289 out_printf(fp, "\n");
2290 out_addline_infile(fp, cc->line_no);
2295 out_printf(fp, "\n");
2296 out_addline_infile(fp, cc->line_no);
2303 out_printf(fp, "\n");
2304 out_addline_infile(fp, cc->line_no);
2307 out_printf(fp, "%s\n", cc->cbuf);
2308 if(cc->cctype == C_CCODE ||
2309 cc->cctype == A_CCODE ||
2310 cc->cctype == AT_CCODE ||
2311 cc->cctype == PH_CCODE)
2312 out_addline_outfile(fp);
2316 print_class_block(Class *c)
2320 gboolean printed_private = FALSE;
2323 out_printf(out, "/* utility types we may need */\n");
2324 if(special_array[SPECIAL_2POINTER])
2325 out_printf(out, "typedef struct { "
2326 "gpointer a; gpointer b; "
2327 "} ___twopointertype;\n");
2328 if(special_array[SPECIAL_3POINTER])
2329 out_printf(out, "typedef struct { "
2330 "gpointer a; gpointer b; "
2332 "} ___threepointertype;\n");
2333 if(special_array[SPECIAL_INT_POINTER])
2334 out_printf(out, "typedef struct { "
2335 "gint a; gpointer b; "
2336 "} ___intpointertype;\n");
2337 out_printf(out, "\n");
2340 out_printf(outh, "\n/*\n"
2341 " * Type checking and casting macros\n"
2343 out_printf(outh, "#define %s\t"
2344 "(%s_get_type())\n",
2345 macrotype, funcbase);
2346 out_printf(outh, "#define %s(obj)\t"
2347 "GTK_CHECK_CAST((obj), %s_get_type(), %s)\n",
2348 macrobase, funcbase, typebase);
2349 out_printf(outh, "#define %s_CONST(obj)\t"
2350 "GTK_CHECK_CAST((obj), %s_get_type(), %s const)\n",
2351 macrobase, funcbase, typebase);
2352 out_printf(outh, "#define %s_CLASS(klass)\t"
2353 "GTK_CHECK_CLASS_CAST((klass), %s_get_type(), %sClass)\n",
2354 macrobase, funcbase, typebase);
2355 out_printf(outh, "#define %s(obj)\t"
2356 "GTK_CHECK_TYPE((obj), %s_get_type ())\n\n",
2358 out_printf(outh, "#ifdef GTK_CHECK_GET_CLASS\n"
2359 "#define %s_GET_CLASS(obj)\t"
2360 "GTK_CHECK_GET_CLASS((obj), %s_get_type(), %sClass)\n",
2361 macrobase, funcbase, typebase);
2362 out_printf(outh, "#else /* !GTK_CHECK_GET_CLASS */\n"
2363 "#define %s_GET_CLASS(obj)\t"
2364 "((%sClass *)GTK_OBJECT(obj)->klass)\n"
2365 "#endif /* GTK_CHECK_GET_CLASS */\n",
2366 macrobase, typebase);
2368 if( ! no_self_alias) {
2369 out_printf(out, "/* self casting macros */\n");
2370 out_printf(out, "#define SELF(x) %s(x)\n", macrobase);
2371 out_printf(out, "#define SELF_CONST(x) %s_CONST(x)\n", macrobase);
2372 out_printf(out, "#define IS_SELF(x) %s(x)\n", macrois);
2373 out_printf(out, "#define TYPE_SELF %s\n", macrotype);
2374 out_printf(out, "#define SELF_CLASS(x) %s_CLASS(x)\n\n",
2376 out_printf(out, "#define SELF_GET_CLASS(x) %s_GET_CLASS(x)\n\n",
2379 out_printf(out, "/* self typedefs */\n");
2380 out_printf(out, "typedef %s Self;\n", typebase);
2381 out_printf(out, "typedef %sClass SelfClass;\n\n", typebase);
2384 out_printf(out, "/* GTK_CLASS_TYPE for 1.2<->1.3/2.0 GTK+ compatibility */\n");
2386 "#ifndef GTK_CLASS_TYPE\n"
2387 "#define GTK_CLASS_TYPE(x) (GTK_OBJECT_CLASS(x)->type)\n"
2388 "#endif /* GTK_CLASS_TYPE */\n\n");
2390 if(privates > 0 || always_private_struct) {
2391 out_printf(outh, "\n/* Private structure type */\n");
2392 out_printf(outh, "typedef struct _%sPrivate %sPrivate;\n",
2393 typebase, typebase);
2395 out_printf(outh, "/* There are no privates, this "
2396 "structure is thus never defined */\n");
2399 out_printf(outh, "\n/*\n"
2400 " * Main object structure\n"
2402 s = replace_sep(c->otype, '_');
2404 out_printf(outh, "#ifndef __TYPEDEF_%s__\n"
2405 "#define __TYPEDEF_%s__\n", s, s);
2407 out_printf(outh, "typedef struct _%s %s;\n"
2408 "#endif\n", typebase, typebase);
2409 out_printf(outh, "struct _%s {\n\t%s __parent__;\n",
2410 typebase, ptypebase);
2411 for(l=c->nodes; l; l=g_list_next(l)) {
2412 static gboolean printed_public = FALSE;
2414 Variable *v = (Variable *)n;
2415 if(n->type == VARIABLE_NODE &&
2416 v->scope == PUBLIC_SCOPE) {
2417 if( ! printed_public) {
2418 out_printf(outh, "\t/*< public >*/\n");
2419 printed_public = TRUE;
2421 put_variable((Variable *)n, outh);
2424 /* put protecteds always AFTER publics */
2425 for(l=c->nodes; l; l=g_list_next(l)) {
2427 Variable *v = (Variable *)n;
2428 if(n->type == VARIABLE_NODE &&
2429 v->scope == PROTECTED_SCOPE) {
2430 if( ! printed_private) {
2431 out_printf(outh, "\t/*< private >*/\n");
2432 printed_private = TRUE;
2434 put_variable((Variable *)n, outh);
2437 if(privates > 0 || always_private_struct) {
2438 if( ! printed_private)
2439 out_printf(outh, "\t/*< private >*/\n");
2440 out_printf(outh, "\t%sPrivate *_priv;\n", typebase);
2442 out_printf(outh, "};\n");
2447 /* if we are to stick this into the private
2448 header, if not stick it directly into the
2455 out_printf(outfp, "struct _%sPrivate {\n",
2457 for(l=c->nodes; l; l=l->next) {
2459 Variable *v = (Variable *)n;
2460 if(n->type == VARIABLE_NODE &&
2461 v->scope == PRIVATE_SCOPE) {
2462 out_addline_infile(outfp, v->line_no);
2463 put_variable(v, outfp);
2466 out_addline_outfile(outfp);
2467 out_printf(outfp, "};\n");
2470 out_printf(outh, "\n/*\n"
2471 " * Class definition\n"
2473 out_printf(outh, "typedef struct _%sClass %sClass;\n",
2474 typebase, typebase);
2476 "struct _%sClass {\n\t%sClass __parent__;\n",
2477 typebase, ptypebase);
2478 for(l = c->nodes; l != NULL; l = l->next) {
2480 if(n->type == METHOD_NODE)
2481 put_vs_method((Method *)n);
2483 /* If BonoboX type class put down the epv */
2484 if (c->bonobo_x_class != NULL) {
2486 "\t/* Bonobo object epv */\n"
2487 "\tPOA_%s__epv _epv;\n",
2490 /* put class scope variables */
2491 for(l = c->nodes; l != NULL; l = l->next) {
2493 Variable *v = (Variable *)n;
2494 if(n->type == VARIABLE_NODE &&
2495 v->scope == CLASS_SCOPE)
2496 put_variable((Variable *)n, outh);
2498 out_printf(outh, "};\n\n");
2500 out_printf(out, "/* here are local prototypes */\n");
2501 if(set_arguments > 0) {
2502 out_printf(out, "static void ___object_set_arg "
2503 "(GtkObject *object, GtkArg *arg, "
2504 "guint arg_id);\n");
2506 if(get_arguments > 0) {
2507 out_printf(out, "static void ___object_get_arg "
2508 "(GtkObject *object, GtkArg *arg, "
2509 "guint arg_id);\n");
2512 out_printf(outh, "\n/*\n"
2513 " * Public methods\n"
2516 if ( ! overrode_get_type) {
2517 out_printf(outh, "GtkType\t%s_get_type\t(void)", funcbase);
2519 out_printf(outh, " G_GNUC_CONST;\n");
2521 out_printf(outh, ";\n");
2525 for(l = c->nodes; l != NULL; l = l->next) {
2527 if(n->type == METHOD_NODE) {
2528 put_pub_method((Method *)n);
2529 put_prot_method((Method *)n);
2530 put_priv_method_prot((Method *)n);
2534 /* this idea is less and less apealing to me */
2536 out_printf (outh, "\n/*\n"
2537 " * Signal connection wrapper macros\n"
2540 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
2541 put_signal_macros (c, TRUE);
2542 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
2543 put_signal_macros (c, FALSE);
2544 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n");
2546 put_signal_macros (c, FALSE);
2550 /* argument wrapping macros */
2551 if(get_arguments > 0 || set_arguments > 0) {
2552 out_printf(outh, "\n/*\n"
2553 " * Argument wrapping macros\n"
2556 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
2557 put_argument_gnu_wrappers(c);
2558 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
2559 put_argument_nongnu_wrappers(c);
2560 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n");
2562 put_argument_nongnu_wrappers(c);
2567 for(l = c->nodes; l != NULL; l = l->next) {
2569 if(n->type == METHOD_NODE)
2570 add_signal_prots((Method *)n);
2576 if ( ! overrode_get_type) {
2577 if (c->bonobo_x_class != NULL)
2578 add_bonobo_x_get_type ();
2583 if(any_method_to_alias(c)) {
2585 out_printf(out, "/* Short form macros */\n");
2586 out_printf(out, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
2587 make_method_gnu_aliases(c);
2588 out_printf(out, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n");
2590 make_method_nongnu_aliases(c);
2593 out_printf(out, "/* a macro for creating a new object of our type */\n");
2595 "#define GET_NEW ((%s *)gtk_type_new(%s_get_type()))\n\n",
2596 typebase, funcbase);
2606 if(set_arguments > 0) {
2607 add_getset_arg(c, TRUE);
2610 if(get_arguments > 0) {
2611 add_getset_arg(c, FALSE);
2614 for(l = c->nodes; l != NULL; l = l->next) {
2616 if(n->type == METHOD_NODE)
2617 put_method((Method *)n);
2620 add_bad_hack_to_avoid_unused_warnings(c);
2624 print_version_macros(void)
2626 int major=0, minor=0, pl=0;
2627 sscanf(VERSION, "%d.%d.%d", &major, &minor, &pl);
2629 out_printf(out, "#define GOB_VERSION_MAJOR %d\n", major);
2630 out_printf(out, "#define GOB_VERSION_MINOR %d\n", minor);
2631 out_printf(out, "#define GOB_VERSION_PATCHLEVEL %d\n\n", pl);
2635 print_file_comments(void)
2639 out_printf(outh, "/* Generated by GOB (v%s)"
2640 " (do not edit directly) */\n\n", VERSION);
2642 out_printf(outph, "/* Generated by GOB (v%s)"
2643 " (do not edit directly) */\n\n", VERSION);
2644 out_printf(out, "/* Generated by GOB (v%s) on %s"
2645 " (do not edit directly) */\n\n",
2646 VERSION, ctime(&curtime));
2648 out_printf(out, "/* End world hunger, donate to the World Food Programme, http://www.wfp.org */\n\n");
2652 print_includes(void)
2654 gboolean found_header;
2657 /* We may need string.h for memset */
2658 if(destructors > 0 &&
2659 ! g_list_find_custom(include_files, "string.h", (GCompareFunc)strcmp)) {
2660 out_printf(out, "#include <string.h> /* memset() */\n\n");
2663 p = g_strconcat(filebase, ".h", NULL);
2664 found_header = TRUE;
2665 if( ! g_list_find_custom(include_files, p, (GCompareFunc)strcmp)) {
2666 out_printf(out, "#include \"%s.h\"\n\n", filebase);
2667 found_header = FALSE;
2671 /* if we are creating a private header see if it was included */
2673 p = g_strconcat(filebase, "-private.h", NULL);
2674 if( ! g_list_find_custom(include_files, p,
2675 (GCompareFunc)strcmp)) {
2676 out_printf(out, "#include \"%s-private.h\"\n\n",
2679 error_printf(GOB_WARN, 0,
2680 "Implicit private header include "
2682 "\tsource file, while public "
2683 "header is at a custom location, "
2685 "\texplicitly include "
2686 "the private header below the "
2694 print_header_prefixes(void)
2698 p = replace_sep(((Class *)class)->otype, '_');
2700 out_printf(outh, "#ifndef __%s_H__\n#define __%s_H__\n\n", p, p);
2702 out_printf(outph, "#ifndef __%s_PRIVATE_H__\n"
2703 "#define __%s_PRIVATE_H__\n\n"
2704 "#include \"%s.h\"\n\n", p, p, filebase);
2707 if( ! no_extern_c) {
2708 out_printf(outh, "#ifdef __cplusplus\n"
2710 "#endif /* __cplusplus */\n\n");
2712 out_printf(outph, "#ifdef __cplusplus\n"
2714 "#endif /* __cplusplus */\n\n");
2719 print_header_postfixes(void)
2722 out_printf(outh, "\n#ifdef __cplusplus\n"
2724 "#endif /* __cplusplus */\n");
2725 out_printf(outh, "\n#endif\n");
2728 out_printf(outph, "\n#ifdef __cplusplus\n"
2730 "#endif /* __cplusplus */\n");
2731 out_printf(outph, "\n#endif\n");
2740 /* print the AT_CCODE blocks */
2741 for(li = nodes; li != NULL; li = li->next) {
2742 Node *node = li->data;
2743 if(node->type == CCODE_NODE) {
2744 CCode *cc = (CCode *)node;
2745 if(cc->cctype == AT_CCODE)
2746 print_ccode_block((CCode *)node);
2752 print_header_top(void)
2756 /* mandatory include */
2757 out_printf(outh, "#include <gtk/gtk.h>\n\n");
2759 /* print the HT_CCODE blocks */
2760 for(li=nodes;li;li=g_list_next(li)) {
2761 Node *node = li->data;
2762 if(node->type == CCODE_NODE) {
2763 CCode *cc = (CCode *)node;
2764 if(cc->cctype == HT_CCODE)
2765 print_ccode_block((CCode *)node);
2771 generate_outfiles(void)
2775 print_file_comments();
2781 print_header_prefixes();
2783 print_version_macros();
2787 for(li=nodes;li;li=g_list_next(li)) {
2788 Node *node = li->data;
2789 if(node->type == CCODE_NODE) {
2790 CCode *cc = (CCode *)node;
2791 if(cc->cctype != HT_CCODE &&
2792 cc->cctype != AT_CCODE)
2793 print_ccode_block((CCode *)node);
2794 } else if(node->type == CLASS_NODE) {
2795 print_class_block((Class *)node);
2797 g_assert_not_reached();
2800 print_header_postfixes();
2806 fprintf(stderr, "Gob version %s\n\n", VERSION);
2807 fprintf(stderr, "gob [options] file.gob\n\n");
2808 fprintf(stderr, "Options:\n"
2809 "\t--help,-h,-? Display this help\n"
2810 "\t--version Display version\n"
2811 "\t--exit-on-warn,-w Exit with an error on warnings\n"
2812 "\t--no-exit-on-warn Don't exit on warnings [default]\n"
2813 "\t--for-cpp Create C++ files\n"
2814 "\t--no-extern-c Never print extern \"C\" into the "
2816 "\t--no-gnu Never use GNU extentions\n"
2817 "\t--no-touch-headers Don't touch headers unless they "
2819 "\t--always-private-header Always create a private header "
2821 "\t even if it would be empty "
2823 "\t--ondemand-private-header Create private header only when "
2825 "\t--no-private-header Don't create a private header, "
2827 "\t structure and protected "
2828 "prototypes inside c file\n"
2829 "\t--always-private-struct Always create a private pointer "
2831 "\t the object structure\n"
2832 "\t--no-write,-n Don't write output files, just "
2834 "\t--no-lines Don't print '#line' to output\n"
2835 "\t--no-self-alias Don't create self type and macro "
2837 "\t--no-kill-underscores Don't remove the leading underscore "
2839 "\t short id names\n");
2843 parse_options(int argc, char *argv[])
2846 int got_file = FALSE;
2847 int no_opts = FALSE;
2851 for(i = 1 ; i < argc; i++) {
2853 argv[i][0] != '-') {
2856 fprintf(stderr, "Specify only one file!\n");
2862 } else if(strcmp(argv[i], "--help")==0) {
2865 } else if(strcmp(argv[i], "--version")==0) {
2866 fprintf(stderr, "Gob version %s\n", VERSION);
2868 } else if(strcmp(argv[i], "--exit-on-warn")==0) {
2869 exit_on_warn = TRUE;
2870 } else if(strcmp(argv[i], "--no-exit-on-warn")==0) {
2871 exit_on_warn = FALSE;
2872 } else if(strcmp(argv[i], "--for-cpp")==0) {
2874 } else if(strcmp(argv[i], "--no-touch-headers")==0) {
2875 no_touch_headers = TRUE;
2876 } else if(strcmp(argv[i], "--ondemand-private-header")==0) {
2877 private_header = PRIVATE_HEADER_ONDEMAND;
2878 } else if(strcmp(argv[i], "--always-private-header")==0) {
2879 private_header = PRIVATE_HEADER_ALWAYS;
2880 } else if(strcmp(argv[i], "--no-private-header")==0) {
2881 private_header = PRIVATE_HEADER_NEVER;
2882 } else if(strcmp(argv[i], "--no-gnu")==0) {
2884 } else if(strcmp(argv[i], "--no-extern-c")==0) {
2886 } else if(strcmp(argv[i], "--no-write")==0) {
2888 } else if(strcmp(argv[i], "--no-lines")==0) {
2890 } else if(strcmp(argv[i], "--no-self-alias")==0) {
2891 no_self_alias = TRUE;
2892 } else if(strcmp(argv[i], "--no-kill-underscores")==0) {
2893 no_kill_underscores = TRUE;
2894 } else if(strcmp(argv[i], "--always-private-struct")==0) {
2895 always_private_struct = TRUE;
2896 } else if(strcmp(argv[i], "--")==0) {
2897 /*further arguments are files*/
2899 } else if(strncmp(argv[i], "--", 2)==0) {
2900 /*unknown long option*/
2901 fprintf(stderr, "Unknown option '%s'!\n", argv[i]);
2905 /*by now we know we have a string starting with
2906 - which is a short option string*/
2908 for(p = argv[i] + 1; *p; p++) {
2922 "Unknown option '%c'!\n", *p);
2931 /* this is a somewhat ugly hack, but it appears to work */
2933 compare_and_move_header(void)
2935 char *hfnew = g_strconcat("#gob#", filebase, ".h#gob#", NULL);
2936 char *hf = g_strconcat(filebase, ".h", NULL);
2938 if(stat(hf, &s) == 0) {
2940 s = g_strdup_printf("cmp '%s' '%s' > /dev/null", hf, hfnew);
2941 if(system(s) == 0) {
2942 if(unlink(hfnew) != 0)
2943 error_printf(GOB_ERROR, 0,
2944 "Can't remove new header file");
2952 error_printf(GOB_ERROR, 0,
2953 "Can't remove old header file");
2955 if(rename(hfnew, hf) != 0)
2956 error_printf(GOB_ERROR, 0,
2957 "Can't rename new header file");
2963 main(int argc, char *argv[])
2965 parse_options(argc, argv);
2968 yyin = fopen(filename, "r");
2970 fprintf(stderr, "Error: can't open file '%s'\n",
2977 /* This is where parsing is done */
2980 g_error("Parsing errors, quitting");
2983 error_print(GOB_ERROR, 0, " no class defined");
2986 exit_on_error = FALSE;
2988 signals = count_signals((Class *)class);
2989 set_arguments = count_set_arguments((Class *)class);
2990 get_arguments = count_get_arguments((Class *)class);
2991 overrides = count_overrides((Class *)class);
2992 privates = count_privates((Class *)class);
2993 protecteds = count_protecteds((Class *)class);
2994 destructors = count_destructors((Class *)class);
2995 initializers = count_initializers((Class *)class);
2996 overrode_get_type = find_get_type((Class *)class);
2999 make_inits((Class *)class);
3000 if(destructors > 0) {
3001 need_destroy = TRUE;
3002 find_destroy((Class *)class);
3005 need_finalize = TRUE;
3006 find_finalize((Class *)class);
3008 check_bad_symbols((Class *)class);
3009 check_duplicate_symbols((Class *)class);
3010 check_duplicate_overrides((Class *)class);
3011 check_duplicate_signals_args((Class *)class);
3012 check_public_new((Class *)class);
3013 check_vararg((Class *)class);
3014 check_firstarg((Class *)class);
3015 check_nonvoidempty((Class *)class);
3016 check_signal_args((Class *)class);
3017 check_argument_types((Class *)class);
3018 check_func_arg_checks((Class *)class);
3020 exit_on_error = TRUE;
3025 any_special = setup_special_array((Class *)class, special_array);
3029 generate_outfiles();
3040 if(no_touch_headers &&
3042 compare_and_move_header();