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(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");
703 add_signal_prots(Method *m)
710 if(m->method != SIGNAL_LAST_METHOD &&
711 m->method != SIGNAL_FIRST_METHOD)
715 marsh = g_hash_table_new(NULL, NULL);
717 if(strcmp(m->gtktypes->data, "NONE")==0 &&
718 strcmp(m->gtktypes->next->data, "NONE")==0)
721 /* if we already did a signal prototype just use that */
722 mm = find_same_type_signal(m);
724 s = g_hash_table_lookup(marsh, mm);
725 g_hash_table_insert(marsh, m, s);
729 s = g_strdup_printf("Sig%d", sig++);
731 g_hash_table_insert(marsh, m, s);
732 eq_signal_methods = g_list_prepend(eq_signal_methods, m);
734 /* we know that we'll know all the gtktypes (so get_cast can't fail) */
735 out_printf(out, "\ntypedef %s (*___%s) (%s *, ",
736 get_cast(m->gtktypes->data, FALSE), s, typebase);
738 if(strcmp(m->gtktypes->next->data, "NONE")!=0) {
739 for(li=m->gtktypes->next; li; li=g_list_next(li))
740 out_printf(out, "%s, ", get_cast(li->data, FALSE));
742 out_printf(out, "gpointer);\n");
744 out_printf(out, "\nstatic void\n"
745 "___marshal_%s (GtkObject * object,\n"
746 "\tGtkSignalFunc func,\n"
747 "\tgpointer func_data,\n"
751 if(strcmp(m->gtktypes->data, "NONE")==0) {
752 out_printf(out, "\t___%s rfunc;\n\n"
753 "\trfunc = (___%s)func;\n\n"
754 "\t(*rfunc)((%s *)object", s, s, typebase);
756 const char *retcast = get_cast(m->gtktypes->data, FALSE);
757 gboolean is_none = (strcmp(m->gtktypes->next->data, "NONE")==0);
761 "\trfunc = (___%s)func;\n\n"
762 "\tretval = GTK_RETLOC_%s(args[%d]);\n\n"
763 "\t*retval = (*rfunc)((%s *)object",
765 (char *)m->gtktypes->data,
766 g_list_length(m->gtktypes) - (is_none ? 2 : 1),
769 print_signal_marsal_args(m);
777 out_printf(out, "\n");
779 out_printf(out, "enum {\n");
780 for(li=c->nodes;li;li=g_list_next(li)) {
782 if(n->type == METHOD_NODE) {
783 Method *m = (Method *)n;
784 if(m->method == SIGNAL_LAST_METHOD ||
785 m->method == SIGNAL_FIRST_METHOD) {
786 char *s = g_strdup(get_real_id(m->id));
788 out_printf(out, "\t%s_SIGNAL,\n", s);
793 out_printf(out, "\tLAST_SIGNAL\n};\n\n");
795 if(set_arguments > 0 || get_arguments > 0) {
796 out_printf(out, "enum {\n\tARG_0");
797 for(li=c->nodes;li;li=g_list_next(li)) {
799 if(n->type == ARGUMENT_NODE) {
800 Argument *a = (Argument *)n;
801 char *s = g_strdup(a->name);
803 out_printf(out, ",\n\tARG_%s", s);
807 out_printf(out, "\n};\n\n");
812 "static guint object_signals[LAST_SIGNAL] = {0};\n\n");
814 out_printf(out, "/* pointer to the class of our parent */\n");
815 out_printf(out, "static %sClass *parent_class = NULL;\n\n", ptypebase);
821 char *chunk_size = ((Class*)class)->chunk_size;
825 "%s_get_type (void)\n"
827 "\tstatic GtkType type = 0;\n\n"
828 "\tif (type == 0) {\n"
829 "\t\tstatic const GtkTypeInfo info = {\n"
831 "\t\t\tsizeof (%s),\n"
832 "\t\t\tsizeof (%sClass),\n"
833 "\t\t\t(GtkClassInitFunc) %s_class_init,\n"
834 "\t\t\t(GtkObjectInitFunc) %s_init,\n"
835 "\t\t\t/* reserved_1 */ NULL,\n"
836 "\t\t\t/* reserved_2 */ NULL,\n"
837 "\t\t\t(GtkClassInitFunc) NULL\n"
839 "\t\ttype = gtk_type_unique (%s_get_type(), &info);\n",
840 funcbase, typebase, typebase, typebase,
841 funcbase, funcbase, pfuncbase);
845 "\t\tgtk_type_set_chunk_alloc(type, %s);\n"
847 chunk_size, chunk_size);
856 add_bonobo_x_get_type (void)
858 char *chunk_size = ((Class*)class)->chunk_size;
862 "%s_get_type (void)\n"
864 "\tstatic GtkType type = 0;\n\n"
865 "\tif (type == 0) {\n"
866 "\t\tstatic const GtkTypeInfo info = {\n"
868 "\t\t\tsizeof (%s),\n"
869 "\t\t\tsizeof (%sClass),\n"
870 "\t\t\t(GtkClassInitFunc) %s_class_init,\n"
871 "\t\t\t(GtkObjectInitFunc) %s_init,\n"
872 "\t\t\t/* reserved_1 */ NULL,\n"
873 "\t\t\t/* reserved_2 */ NULL,\n"
874 "\t\t\t(GtkClassInitFunc) NULL\n"
876 "\t\ttype = bonobo_x_type_unique\n"
877 "\t\t\t(%s_get_type (),\n"
878 "\t\t\tPOA_%s__init, NULL,\n"
879 "\t\t\tGTK_STRUCT_OFFSET (%sClass, _epv),\n"
881 funcbase, typebase, typebase, typebase,
882 funcbase, funcbase, pfuncbase,
883 ((Class*)class)->bonobo_x_class,
888 "\t\tgtk_type_set_chunk_alloc(type, %s);\n"
890 chunk_size, chunk_size);
899 add_overrides(Class *c, const char *oname, gboolean did_base_obj)
905 done = g_hash_table_new(g_str_hash, g_str_equal);
907 s = g_strdup("GtkObject"); /* This was already done */
908 g_hash_table_insert(done, s, s);
909 s = g_strdup("GObject"); /* This was probably already done as well (if using Gtk/Glib 1.3/2.0) */
910 g_hash_table_insert(done, s, s);
912 for(li=c->nodes; li; li=g_list_next(li)) {
915 Method *m = (Method *)n;
916 if(n->type != METHOD_NODE ||
917 m->method != OVERRIDE_METHOD)
920 s = remove_sep(m->otype);
922 if(g_hash_table_lookup(done, s)) {
926 g_hash_table_insert(done, s, s);
928 f = replace_sep(m->otype, '_');
931 out_printf(out, "\t%sClass *%s_class = (%sClass *)%s;\n",
936 g_hash_table_foreach(done, (GHFunc)g_free, NULL);
937 g_hash_table_destroy(done);
941 make_run_signal_flags(Method *m, gboolean last)
955 gs = g_string_new(NULL);
958 g_string_assign(gs, "GTK_RUN_LAST");
960 g_string_assign(gs, "GTK_RUN_FIRST");
962 if(m->scope == PUBLIC_SCOPE)
963 g_string_append(gs, " | GTK_RUN_ACTION");
965 for(li = m->flags; li; li = li->next) {
966 char *flag = li->data;
968 for(i=0;flags[i];i++) {
969 if(strcmp(flags[i], flag)==0)
972 /* if we haven't found it in our list */
974 error_printf(GOB_WARN, m->line_no,
975 "Unknown flag '%s' used, "
976 "perhaps it was misspelled",
979 g_string_sprintfa(gs, " | GTK_RUN_%s", flag);
984 g_string_free(gs, FALSE);
991 add_signals(Class *c)
995 out_printf(out, "\n");
996 for(li=c->nodes;li;li=g_list_next(li)) {
998 char *mar, *sig, *flags;
999 gboolean is_none, last = FALSE;
1000 Method *m = (Method *)n;
1002 if(n->type != METHOD_NODE ||
1003 (m->method != SIGNAL_FIRST_METHOD &&
1004 m->method != SIGNAL_LAST_METHOD))
1007 if(m->method == SIGNAL_FIRST_METHOD)
1012 if(g_hash_table_lookup(marsh, m))
1013 mar = g_strconcat("___marshal_",
1014 (char *)g_hash_table_lookup(marsh, m),
1017 mar = g_strdup("gtk_signal_default_marshaller");
1019 is_none = (strcmp(m->gtktypes->next->data, "NONE")==0);
1021 sig = g_strdup(get_real_id(m->id));
1023 flags = make_run_signal_flags(m, last);
1024 out_printf(out, "\tobject_signals[%s_SIGNAL] =\n"
1025 "\t\tgtk_signal_new (\"%s\",\n"
1026 "\t\t\t(GtkSignalRunType)(%s),\n"
1027 "\t\t\tGTK_CLASS_TYPE(gtk_object_class),\n"
1028 "\t\t\tGTK_SIGNAL_OFFSET (%sClass, %s),\n"
1030 "\t\t\tGTK_TYPE_%s, %d",
1031 sig, get_real_id(m->id),
1033 typebase, get_real_id(m->id), mar,
1034 (char *)m->gtktypes->data,
1035 is_none ? 0 : g_list_length(m->gtktypes->next));
1042 for(l = m->gtktypes->next; l != NULL; l = l->next)
1043 out_printf(out, ",\n\t\t\tGTK_TYPE_%s",
1047 out_printf(out, ");\n");
1049 if(strcmp(m->gtktypes->data, "NONE") != 0 ||
1053 out_printf(out, "\tif(");
1054 if(strcmp(m->gtktypes->data, "NONE") != 0) {
1055 out_printf(out, "%s sizeof(", sep);
1056 print_type(out, m->mtype, FALSE);
1057 out_printf(out, "%s",
1059 m->mtype->postfix : "");
1060 out_printf(out, ") != sizeof(%s)",
1061 get_cast(m->gtktypes->data, FALSE));
1066 for(al = m->args->next, gl = m->gtktypes->next;
1067 al != NULL && gl != NULL;
1068 al = al->next, gl = gl->next) {
1069 FuncArg *arg = al->data;
1070 char *gtkarg = gl->data;
1072 out_printf(out, "%ssizeof(", sep);
1073 print_type(out, arg->atype, FALSE);
1074 out_printf(out, "%s",
1075 arg->atype->postfix ?
1076 arg->atype->postfix : "");
1077 out_printf(out, ") != sizeof(%s)",
1078 get_cast(gtkarg, FALSE));
1082 out_printf(out, ") {\n"
1083 "\t\tg_error(\"%s line %d: Type mismatch "
1084 "of \\\"%s\\\" signal signature\");\n"
1086 filename, m->line_no, get_real_id(m->id));
1090 out_printf(out, "\tgtk_object_class_add_signals (gtk_object_class,\n"
1091 "\t\tobject_signals, LAST_SIGNAL);\n\n");
1095 set_def_handlers(Class *c, const char *oname)
1098 gboolean set_line = FALSE;
1100 out_printf(out, "\n");
1101 for(li = c->nodes; li; li = g_list_next(li)) {
1103 Method *m = (Method *)n;
1105 if(n->type != METHOD_NODE ||
1106 (m->method != SIGNAL_FIRST_METHOD &&
1107 m->method != SIGNAL_LAST_METHOD &&
1108 m->method != VIRTUAL_METHOD &&
1109 m->method != OVERRIDE_METHOD))
1112 if(m->line_no > 0 && m->cbuf) {
1113 out_addline_infile(out, m->line_no);
1115 } else if(set_line) {
1116 out_addline_outfile(out);
1121 if(m->method == OVERRIDE_METHOD) {
1123 s = replace_sep(m->otype, '_');
1128 strcmp(get_real_id(m->id), "destroy") == 0)
1129 out_printf(out, "\tgtk_object_class->destroy "
1131 else if(need_finalize &&
1133 strcmp(get_real_id(m->id), "finalize") == 0)
1135 "#ifdef G_OBJECT_CLASS\n"
1136 "\tg_object_class->finalize = ___finalize;\n"
1137 "#else /* !G_OBJECT_CLASS */\n"
1138 "\tgtk_object_class->finalize = ___finalize;\n"
1139 "#endif /* G_OBJECT_CLASS */\n");
1142 "\t%s_class->%s = ___%x_%s_%s;\n",
1143 s, get_real_id(m->id), (guint)m->unique_id,
1144 funcbase, get_real_id(m->id));
1146 out_printf(out, "\t%s_class->%s = NULL;\n",
1147 s, get_real_id(m->id));
1150 out_printf(out, "\t%s->%s = ___real_%s_%s;\n",
1151 oname, get_real_id(m->id),
1152 funcbase, get_real_id(m->id));
1154 out_printf(out, "\t%s->%s = NULL;\n",
1155 oname, get_real_id(m->id));
1159 out_addline_outfile(out);
1163 make_arguments(Class *c)
1166 char *argflags[] = {
1174 out_printf(out, "\n");
1175 for(li=c->nodes;li;li=g_list_next(li)) {
1181 if(n->type != ARGUMENT_NODE)
1186 if(a->get && a->set)
1187 flags = g_string_new("GTK_ARG_READWRITE");
1189 flags = g_string_new("GTK_ARG_READABLE");
1191 flags = g_string_new("GTK_ARG_WRITABLE");
1193 g_assert(a->get || a->set);
1195 for(l=a->flags;l;l=g_list_next(l)) {
1196 char *flag = l->data;
1198 if(strcmp(flag, "READWRITE")==0 ||
1199 strcmp(flag, "READABLE")==0 ||
1200 strcmp(flag, "WRITABLE")==0) {
1201 error_print(GOB_WARN, a->line_no,
1202 "READWRITE, READABLE and "
1203 "WRITABLE argument flags are "
1204 "set automatically");
1207 for(i = 0; argflags[i]; i++) {
1208 if(strcmp(argflags[i], flag)==0)
1211 /* if we haven't found it in our list */
1212 if( ! argflags[i]) {
1213 error_printf(GOB_WARN, a->line_no,
1214 "Unknown flag '%s' used, "
1215 "perhaps it was misspelled", flag);
1217 g_string_sprintfa(flags, " | GTK_ARG_%s", flag);
1220 s = g_strdup(a->name);
1222 out_printf(out, "\tgtk_object_add_arg_type(\"%s::%s\",\n"
1223 "\t\tGTK_TYPE_%s,\n"
1226 typebase, a->name, a->gtktype, flags->str, s);
1228 g_string_free(flags, TRUE);
1231 out_printf(out, "\n");
1232 if(get_arguments > 0)
1233 out_printf(out, "\tgtk_object_class->get_arg = ___object_get_arg;\n");
1234 if(set_arguments > 0)
1235 out_printf(out, "\tgtk_object_class->set_arg = ___object_set_arg;\n");
1239 print_initializer(Method *m, Variable *v)
1243 if(v->initializer == NULL)
1246 if(v->scope == PRIVATE_SCOPE)
1247 root = g_strconcat(((FuncArg *)m->args->data)->name,
1250 root = g_strdup(((FuncArg *)m->args->data)->name);
1252 if(v->initializer_line > 0)
1253 out_addline_infile(out, v->initializer_line);
1255 out_printf(out, "\t%s->%s = %s;\n",
1256 root, v->id, v->initializer);
1258 if(v->initializer_line > 0)
1259 out_addline_outfile(out);
1265 print_destructor(Variable *v)
1269 if(v->destructor == NULL)
1272 if(v->scope == PRIVATE_SCOPE)
1273 root = "self->_priv";
1277 if(v->destructor_simple) {
1278 if(v->destructor_line > 0)
1279 out_addline_infile(out, v->destructor_line);
1281 out_printf(out, "\tif(%s->%s) { "
1282 "((*(void (*)(void *))%s)) (%s->%s); "
1283 "%s->%s = NULL; }\n",
1284 root, v->id, v->destructor, root, v->id,
1287 if(v->destructor_line > 0)
1288 out_addline_outfile(out);
1290 out_printf(out, "#define VAR (%s->%s)\n", root, v->id);
1291 out_printf(out, "\t{\n");
1292 if(v->destructor_line > 0)
1293 out_addline_infile(out, v->destructor_line);
1295 out_printf(out, "\t%s}\n", v->destructor);
1297 if(v->destructor_line > 0)
1298 out_addline_outfile(out);
1299 out_printf(out, "\tmemset(&VAR, 0, sizeof(VAR));\n");
1300 out_printf(out, "#undef VAR\n");
1305 add_destroy(Class *c)
1307 out_printf(out, "\nstatic void\n"
1308 "___destroy(GtkObject *obj_self)\n"
1311 "#define __GOB_FUNCTION__ \"%s::destroy\"\n",
1314 if(destructors > 0) {
1315 out_printf(out, "\t%s *self = %s (obj_self);\n",
1316 typebase, macrobase);
1319 if(destroy_handler) {
1320 /* so we get possible bad argument warning */
1321 if(destroy_handler->line_no > 0)
1322 out_addline_infile(out, destroy_handler->line_no);
1323 out_printf(out, "\t___%x_%s_destroy(obj_self);\n",
1324 (guint)destroy_handler->unique_id, funcbase);
1325 if(destroy_handler->line_no > 0)
1326 out_addline_outfile(out);
1329 "\tif(GTK_OBJECT_CLASS(parent_class)->destroy) \\\n"
1330 "\t\t(* GTK_OBJECT_CLASS(parent_class)->destroy)(obj_self);\n");
1333 if(destructors > 0) {
1335 for(li = ((Class *)class)->nodes;
1339 Variable *v = (Variable *)n;
1340 if(n->type == VARIABLE_NODE &&
1341 v->scope != CLASS_SCOPE)
1342 print_destructor(v);
1346 out_printf(out, "\treturn;\n");
1348 out_printf(out, "\tself = NULL;\n");
1349 out_printf(out, "}\n"
1350 "#undef __GOB_FUNCTION__\n\n");
1354 add_finalize(Class *c)
1356 /* Sort of a hack to make it work with gtk+ 1.3/2.0 */
1358 "\n#ifdef G_OBJECT_CLASS\n"
1360 "___finalize(GObject *obj_self)\n"
1361 "#else /* !G_OBJECT_CLASS */\n"
1363 "___finalize(GtkObject *obj_self)\n"
1364 "#endif /* G_OBJECT_CLASS */\n"
1367 "#define __GOB_FUNCTION__ \"%s::finalize\"\n",
1371 out_printf(out, "\t%s *self = %s (obj_self);\n",
1372 typebase, macrobase);
1373 out_printf(out, "\tgpointer priv = self->_priv;\n");
1376 if(finalize_handler) {
1377 /* so we get possible bad argument warning */
1378 if(finalize_handler->line_no > 0)
1379 out_addline_infile(out, finalize_handler->line_no);
1380 out_printf(out, "\t___%x_%s_finalize(obj_self);\n",
1381 (guint)finalize_handler->unique_id, funcbase);
1382 if(finalize_handler->line_no > 0)
1383 out_addline_outfile(out);
1385 /* Sort of a hack to make it work with gtk+ 1.3/2.0 */
1387 "#ifdef G_OBJECT_CLASS\n"
1388 "\tif(G_OBJECT_CLASS(parent_class)->finalize) \\\n"
1389 "\t\t(* G_OBJECT_CLASS(parent_class)->finalize)(obj_self);\n"
1390 "#else /* !G_OBJECT_CLASS */\n"
1391 "\tif(GTK_OBJECT_CLASS(parent_class)->finalize) \\\n"
1392 "\t\t(* GTK_OBJECT_CLASS(parent_class)->finalize)(obj_self);\n"
1393 "#endif /* G_OBJECT_CLASS */\n");
1397 out_printf(out, "\tg_free(priv);\n");
1400 out_printf(out, "}\n"
1401 "#undef __GOB_FUNCTION__\n\n");
1405 make_bonobo_x_epv (Class *c, const char *classname)
1408 gboolean added_line = FALSE;
1410 for (li = c->nodes; li != NULL; li = li->next) {
1412 Method *m = (Method *)n;
1413 if(n->type != METHOD_NODE ||
1414 m->method == OVERRIDE_METHOD)
1417 if (m->bonobo_x_func) {
1418 if(m->line_no > 0) {
1419 out_addline_infile(out, m->line_no);
1421 } else if (m->line_no == 0 &&
1423 out_addline_outfile(out);
1426 out_printf (out, "\t%s->_epv.%s = %s;\n",
1427 classname, m->id, m->id);
1431 out_addline_outfile(out);
1438 for(li=c->nodes;li;li=g_list_next(li)) {
1442 gboolean add_unused_class = FALSE;
1444 if(n->type != METHOD_NODE)
1447 if(m->method == INIT_METHOD) {
1449 out_addline_infile(out, m->line_no);
1450 print_method(out, "static ", "\n", "", " ", "", "\n",
1451 m, FALSE, FALSE, TRUE);
1453 out_addline_outfile(out);
1454 out_printf(out, "{\n"
1455 "#define __GOB_FUNCTION__ \"%s::init\"\n",
1458 out_printf(out, "\t%s->_priv = "
1459 "g_new0 (%sPrivate, 1);\n",
1460 ((FuncArg *)m->args->data)->name,
1462 } else if(always_private_struct) {
1463 out_printf(out, "\t%s->_priv = NULL;\n",
1464 ((FuncArg *)m->args->data)->name);
1466 if(initializers > 0) {
1468 for(li = ((Class *)class)->nodes;
1472 Variable *v = (Variable *)n;
1473 if(n->type != VARIABLE_NODE ||
1474 v->scope == CLASS_SCOPE)
1476 print_initializer(m, v);
1479 } else if(m->method == CLASS_INIT_METHOD) {
1480 gboolean did_base_obj = FALSE;
1483 out_addline_infile(out, m->line_no);
1484 print_method(out, "static ", "\n", "", " ", "", "\n",
1485 m, FALSE, FALSE, TRUE);
1487 out_addline_outfile(out);
1488 out_printf(out, "{\n"
1489 "#define __GOB_FUNCTION__ \"%s::class_init\"\n",
1492 set_arguments > 0 ||
1493 get_arguments > 0 ||
1496 add_unused_class = TRUE;
1498 "\tGtkObjectClass *"
1499 "gtk_object_class = "
1500 "(GtkObjectClass*) %s;\n",
1501 ((FuncArg *)m->args->data)->name);
1503 "#ifdef G_OBJECT_CLASS\n"
1506 "(GObjectClass*) %s;\n"
1507 "#endif /* G_OBJECT_CLASS */\n",
1508 ((FuncArg *)m->args->data)->name);
1509 did_base_obj = TRUE;
1514 ((FuncArg *)m->args->data)->name,
1517 if(initializers > 0) {
1519 for(li = ((Class *)class)->nodes;
1523 Variable *v = (Variable *)n;
1524 if(n->type == VARIABLE_NODE &&
1525 v->scope == CLASS_SCOPE)
1526 print_initializer(m, v);
1530 out_printf(out, "\n\tparent_class = ");
1532 out_printf(out, "(%sClass *)", ptypebase);
1533 out_printf(out, "gtk_type_class (%s_get_type ());\n",
1539 set_def_handlers(c, ((FuncArg *)m->args->data)->name);
1541 /* if there are no handlers for these things, we
1542 * need to set them up here */
1543 if(need_destroy && !destroy_handler)
1544 out_printf(out, "\tgtk_object_class->destroy "
1546 if(need_finalize && !finalize_handler)
1548 "#ifdef G_OBJECT_CLASS\n"
1549 "\tg_object_class->finalize = ___finalize;\n"
1550 "#else /* !G_OBJECT_CLASS */\n"
1551 "\tgtk_object_class->finalize = ___finalize;\n"
1552 "#endif /* G_OBJECT_CLASS */\n");
1554 if(get_arguments > 0 || set_arguments > 0)
1557 if (c->bonobo_x_class != NULL) {
1558 make_bonobo_x_epv (c, ((FuncArg *)m->args->data)->name);
1564 out_printf(out, " {\n");
1565 out_addline_infile(out, m->ccode_line);
1566 out_printf(out, "%s\n", m->cbuf);
1567 out_addline_outfile(out);
1568 out_printf(out, " }\n");
1570 out_printf(out, "\treturn;\n");
1573 ((FuncArg *)m->args->data)->name);
1574 if(add_unused_class) {
1576 "\tgtk_object_class = NULL;\n"
1577 "#ifdef G_OBJECT_CLASS\n"
1578 "\tg_object_class = NULL;\n"
1579 "#endif /* G_OBJECT_CLASS */\n");
1581 out_printf(out, "}\n"
1582 "#undef __GOB_FUNCTION__\n");
1587 add_getset_arg(Class *c, gboolean is_set)
1590 out_printf(out, "\nstatic void\n"
1591 "___object_%s_arg (GtkObject *object,\n"
1594 "#define __GOB_FUNCTION__ \"%s::%s_arg\"\n"
1597 "\tself = %s (object);\n\n"
1598 "\tswitch (arg_id) {\n",
1599 is_set ? "set" : "get",
1600 c->otype, is_set ? "set" : "get",
1601 typebase, macrobase);
1603 for(li=c->nodes;li;li=g_list_next(li)) {
1609 if(n->type != ARGUMENT_NODE)
1614 line_no = a->set_line;
1617 line_no = a->get_line;
1621 s = g_strdup(a->name);
1623 out_printf(out, "\tcase ARG_%s:\n", s);
1624 if(is_set && a->atype) {
1625 char *cast = get_type(a->atype, TRUE);
1626 if(no_gnu || for_cpp) {
1627 out_printf(out, "#define ARG "
1628 "((%s)GTK_VALUE_%s(*arg))\n",
1631 out_printf(out, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
1632 if(strcmp(a->gtktype, "OBJECT")==0) {
1633 out_printf(out, "#define ARG "
1635 "GTK_VALUE_POINTER(*arg); "
1639 out_printf(out, "#define ARG "
1641 "GTK_VALUE_%s(*arg); "
1645 out_printf(out, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
1646 out_printf(out, "#define ARG "
1647 "((%s)GTK_VALUE_%s(*arg))\n",
1649 out_printf(out, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n");
1651 out_printf(out, "\t\t{\n");
1653 } else if(!is_set && strcmp(a->gtktype, "OBJECT")==0) {
1655 "#define ARG (GTK_VALUE_POINTER(*arg))\n"
1659 "#define ARG (GTK_VALUE_%s(*arg))\n"
1665 out_addline_infile(out, line_no);
1666 out_printf(out, "%s\n", cbuf);
1668 out_addline_outfile(out);
1669 out_printf(out, "\t\t}\n\t\tbreak;\n"
1672 out_printf(out, "\tdefault:\n\t\tbreak;\n\t}\n"
1673 "\treturn;\n\tself = NULL;\n\targ = NULL;\n}\n"
1674 "#undef __GOB_FUNCTION__\n");
1678 print_checks(Method *m, FuncArg *fa)
1682 gboolean checked_null = FALSE;
1683 is_void = (strcmp(m->mtype->name, "void")==0 &&
1684 m->mtype->pointer == NULL);
1686 for(li = fa->checks; li; li = g_list_next(li)) {
1687 Check *ch = li->data;
1689 /* point to the method prot in .gob for failed checks */
1691 out_addline_infile(out, m->line_no);
1693 out_printf(out, "\tg_return_if_fail (");
1695 out_printf(out, "\tg_return_val_if_fail (");
1696 switch(ch->chtype) {
1698 out_printf(out, "%s != NULL", fa->name);
1699 checked_null = TRUE;
1702 s = make_pre_macro(fa->atype->name, "IS");
1704 out_printf(out, "%s (%s)", s, fa->name);
1706 /* if not check null, null may be valid */
1707 out_printf(out, "!(%s) || %s (%s)", fa->name,
1712 out_printf(out, "%s < %s", fa->name, ch->number);
1715 out_printf(out, "%s > %s", fa->name, ch->number);
1718 out_printf(out, "%s <= %s", fa->name, ch->number);
1721 out_printf(out, "%s >= %s", fa->name, ch->number);
1724 out_printf(out, "%s == %s", fa->name, ch->number);
1727 out_printf(out, "%s != %s", fa->name, ch->number);
1731 out_printf(out, ");\n");
1733 out_printf(out, ", (");
1734 print_type(out, m->mtype, TRUE);
1735 out_printf(out, ")%s);\n",
1736 m->onerror?m->onerror:"0");
1742 print_preconditions(Method *m)
1746 for(li=m->args;li;li=g_list_next(li)) {
1747 FuncArg *fa = li->data;
1749 print_checks(m, fa);
1752 out_addline_outfile(out);
1756 print_method_body(Method *m, int pre)
1759 out_addline_outfile(out);
1760 out_printf(out, "{\n"
1761 "#define __GOB_FUNCTION__ \"%s::%s\"\n",
1762 ((Class *)class)->otype,
1763 get_real_id(m->id));
1765 print_preconditions(m);
1767 /* Note: the trailing }'s are on one line, this is so
1768 that we get the no return warning correctly and point to
1769 the correct line in the .gob file, yes this is slightly
1770 ugly in the .c file, but that is not supposed to be
1771 human readable anyway. */
1773 out_printf(out, "{\n");
1775 out_addline_infile(out, m->ccode_line);
1776 out_printf(out, "\t%s}", m->cbuf);
1779 /* Note, there is no \n between the last } and this } so that
1780 * errors/warnings reported on the end of the body get pointed to the
1781 * right line in the .gob source */
1782 out_printf(out, "}\n");
1785 out_addline_outfile(out);
1786 out_printf(out, "#undef __GOB_FUNCTION__\n");
1790 put_signal_args(Method *m)
1794 for(ali = m->gtktypes->next, li=m->args->next;
1796 li=li->next, ali=ali->next) {
1797 FuncArg *fa = li->data;
1798 const char *cast = get_cast(ali->data, FALSE);
1799 /* we should have already proved before that
1800 the we know all the types */
1803 out_printf(out, ",\n\t\t(%s)%s", cast,
1809 get_arg_names_for_macro(Method *m)
1813 GString *gs = g_string_new(NULL);
1815 for(li=m->args;li;li=g_list_next(li)) {
1816 FuncArg *arg = li->data;
1817 g_string_sprintfa(gs, "%s___%s", p, arg->name);
1821 g_string_free(gs, FALSE);
1826 put_method(Method *m)
1828 char *s, *args, *doc;
1830 is_void = (strcmp(m->mtype->name, "void")==0 &&
1831 m->mtype->pointer == NULL);
1832 out_printf(out, "\n");
1833 if(m->method != OVERRIDE_METHOD) {
1834 doc = get_gtk_doc(m->id);
1836 out_printf(out, "%s", doc);
1841 case REGULAR_METHOD:
1843 out_addline_infile(out, m->line_no);
1844 if(m->scope == PRIVATE_SCOPE)
1845 print_method(out, "static ", "\n", "", " ", "", "\n",
1846 m, FALSE, FALSE, TRUE);
1847 else /* PUBLIC, PROTECTED */
1848 print_method(out, "", "\n", "", " ", "", "\n",
1849 m, FALSE, FALSE, TRUE);
1850 print_method_body(m, TRUE);
1851 /* the outfile line was added above */
1853 case SIGNAL_FIRST_METHOD:
1854 case SIGNAL_LAST_METHOD:
1856 out_addline_infile(out, m->line_no);
1857 if(m->scope == PRIVATE_SCOPE)
1858 print_method(out, "static ", "\n", "", " ", "", "\n",
1859 m, FALSE, FALSE, TRUE);
1860 else /* PUBLIC, PROTECTED */
1861 print_method(out, "", "\n", "", " ", "", "\n",
1862 m, FALSE, FALSE, TRUE);
1863 out_addline_outfile(out);
1864 out_printf(out, "{\n");
1865 s = g_strdup(get_real_id(m->id));
1867 if(strcmp(m->mtype->name, "void") == 0 &&
1868 m->mtype->pointer == NULL) {
1869 print_preconditions(m);
1870 if(((FuncArg *)m->args->data)->name)
1871 out_printf(out, "\tgtk_signal_emit (GTK_OBJECT (%s),\n"
1872 "\t\tobject_signals[%s_SIGNAL]",
1873 ((FuncArg *)m->args->data)->name, s);
1875 out_printf(out, ");\n}\n");
1877 out_printf(out, "\t");
1878 print_type(out, m->mtype, TRUE);
1879 out_printf(out, "return_val = (");
1880 print_type(out, m->mtype, TRUE);
1882 out_printf(out, ")(%s);\n", m->defreturn);
1884 out_printf(out, ")(%s);\n", m->onerror);
1886 out_printf(out, ")(0);\n");
1887 print_preconditions(m);
1888 out_printf(out, "\tgtk_signal_emit (GTK_OBJECT (%s),\n"
1889 "\t\tobject_signals[%s_SIGNAL]",
1890 ((FuncArg *)m->args->data)->name, s);
1892 out_printf(out, ",\n\t\t&return_val);\n"
1893 "\treturn return_val;\n}\n");
1899 out_addline_infile(out, m->line_no);
1900 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
1901 m, FALSE, FALSE, TRUE);
1902 print_method_body(m, FALSE);
1903 /* the outfile line was added above */
1905 case VIRTUAL_METHOD:
1907 out_addline_infile(out, m->line_no);
1908 if(m->scope==PRIVATE_SCOPE)
1909 print_method(out, "static ", "\n", "", " ", "", "\n",
1910 m, FALSE, FALSE, TRUE);
1911 else /* PUBLIC, PROTECTED */
1912 print_method(out, "", "\n", "", " ", "", "\n",
1913 m, FALSE, FALSE, TRUE);
1914 out_addline_outfile(out);
1915 out_printf(out, "{\n"
1916 "\t%sClass *klass;\n", typebase);
1917 print_preconditions(m);
1918 out_printf(out, "\tklass = %s_GET_CLASS(%s);\n\n"
1919 "\tif(klass->%s)\n",
1920 macrobase, ((FuncArg *)m->args->data)->name,
1921 get_real_id(m->id));
1922 if(strcmp(m->mtype->name, "void") == 0 &&
1923 m->mtype->pointer == NULL) {
1925 out_printf(out, "\t\t(*klass->%s)(%s",
1927 ((FuncArg *)m->args->data)->name);
1928 for(li=m->args->next;li;li=g_list_next(li)) {
1929 FuncArg *fa = li->data;
1930 out_printf(out, ",%s", fa->name);
1932 out_printf(out, ");\n}\n");
1935 out_printf(out, "\t\treturn (*klass->%s)(%s",
1937 ((FuncArg *)m->args->data)->name);
1938 for(li=m->args->next;li;li=g_list_next(li)) {
1939 FuncArg *fa = li->data;
1940 out_printf(out, ",%s", fa->name);
1942 out_printf(out, ");\n"
1945 print_type(out, m->mtype, TRUE);
1947 out_printf(out, ")(%s);\n}\n", m->defreturn);
1949 out_printf(out, ")(%s);\n}\n", m->onerror);
1951 out_printf(out, ")(0);\n}\n");
1957 out_addline_infile(out, m->line_no);
1958 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
1959 m, FALSE, FALSE, TRUE);
1960 print_method_body(m, FALSE);
1961 /* the outfile line was added above */
1963 case OVERRIDE_METHOD:
1967 out_addline_infile(out, m->line_no);
1968 s = g_strdup_printf("\n___%x_", (guint)m->unique_id);
1969 print_method(out, "static ", s, "", " ", "", "\n",
1970 m, FALSE, FALSE, FALSE);
1972 out_addline_outfile(out);
1973 s = replace_sep(m->otype, '_');
1975 args = get_arg_names_for_macro(m);
1977 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
1978 "\t{ if(%s_CLASS(parent_class)->%s) \\\n"
1979 "\t\t(* %s_CLASS(parent_class)->%s)(%s); }\n",
1980 args, s, get_real_id(m->id), s, get_real_id(m->id), args);
1982 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
1983 "\t((%s_CLASS(parent_class)->%s)? \\\n"
1984 "\t\t(* %s_CLASS(parent_class)->%s)(%s): \\\n"
1986 args, s, get_real_id(m->id), s, get_real_id(m->id), args);
1987 out_printf(out, "(");
1988 print_type(out, m->mtype, TRUE);
1989 out_printf(out, ")%s))\n",
1990 m->onerror?m->onerror:"0");
1994 print_method_body(m, TRUE);
1995 /* the outfile line was added above */
1996 out_printf(out, "#undef PARENT_HANDLER\n");
2006 char *outfile, *outfileh, *outfileph;
2009 outfile = g_strconcat(filebase, ".c", NULL);
2011 outfile = g_strconcat(filebase, ".cc", NULL);
2012 if(no_touch_headers)
2013 outfileh = g_strconcat("#gob#", filebase, ".h#gob#", NULL);
2015 outfileh = g_strconcat(filebase, ".h", NULL);
2017 if((privates > 0 || protecteds > 0 ||
2018 private_header == PRIVATE_HEADER_ALWAYS) &&
2019 private_header != PRIVATE_HEADER_NEVER)
2020 outfileph = g_strconcat(filebase, "-private.h", NULL);
2026 devnull = fopen("/dev/null", "w");
2028 g_error("Cannot open null device");
2034 out = fopen(outfile, "w");
2036 g_error("Cannot open outfile: %s", outfile);
2038 outh = fopen(outfileh, "w");
2040 g_error("Cannot open outfile: %s", outfileh);
2042 outph = fopen(outfileph, "w");
2044 g_error("Cannot open outfile: %s", outfileh);
2050 put_argument_nongnu_wrappers(Class *c)
2054 if(get_arguments < 0 && set_arguments < 0)
2057 for(li=c->nodes;li;li=g_list_next(li)) {
2059 Argument *a = (Argument *)n;
2063 if(n->type != ARGUMENT_NODE)
2066 aname = g_strdup(a->name);
2070 cast = get_type(a->atype, TRUE);
2072 cast = g_strdup(get_cast(a->gtktype, TRUE));
2076 out_printf(outh, "#define %s_ARG_%s(arg) \t"
2077 "\"%s\",(%s)(arg)\n",
2078 macrobase, aname, a->name, cast);
2080 out_printf(outh, "#define %s_GET_ARG_%s(arg)\t"
2081 "\"%s\",(%s*)(arg)\n",
2082 macrobase, aname, a->name, cast);
2085 out_printf(outh, "#define %s_ARG_%s(arg) \t"
2087 macrobase, aname, a->name);
2089 out_printf(outh, "#define %s_GET_ARG_%s(arg)\t"
2091 macrobase, aname, a->name);
2099 put_argument_gnu_wrappers(Class *c)
2103 if(get_arguments < 0 && set_arguments < 0)
2106 for(li=c->nodes;li;li=g_list_next(li)) {
2108 Argument *a = (Argument *)n;
2111 if(n->type != ARGUMENT_NODE)
2113 s = g_strdup(a->name);
2116 cast = get_type(a->atype, TRUE);
2118 cast = g_strdup(get_cast(a->gtktype, TRUE));
2121 out_printf(outh, "#define %s_ARG_%s(arg) \t"
2122 "\"%s\",({%sz = (arg); z;})\n",
2123 macrobase, s, a->name, cast);
2125 out_printf(outh, "#define %s_GET_ARG_%s(arg)\t"
2126 "\"%s\",({%s*z = (arg); z;})\n",
2127 macrobase, s, a->name, cast);
2130 out_printf(outh, "#define %s_ARG_%s(arg) \t"
2132 macrobase, s, a->name);
2134 out_printf(outh, "#define %s_GET_ARG_%s(arg)\t"
2136 macrobase, s, a->name);
2144 print_ccode_block(CCode *cc)
2147 switch(cc->cctype) {
2149 /* HT code is printed exactly like normal header
2150 code but is printed before */
2153 out_printf(fp, "\n");
2156 /* AT code is printed exactly like normal 'all'
2157 code but is printed before */
2160 out_printf(outph, "\n");
2161 out_printf(outph, "%s\n", cc->cbuf);
2162 out_addline_infile(outph, cc->line_no);
2163 out_addline_outfile(outph);
2165 out_printf(outh, "\n");
2166 out_printf(outh, "%s\n", cc->cbuf);
2168 out_printf(fp, "\n");
2169 out_addline_infile(fp, cc->line_no);
2174 out_printf(fp, "\n");
2175 out_addline_infile(fp, cc->line_no);
2182 out_printf(fp, "\n");
2183 out_addline_infile(fp, cc->line_no);
2186 out_printf(fp, "%s\n", cc->cbuf);
2187 if(cc->cctype == C_CCODE ||
2188 cc->cctype == A_CCODE ||
2189 cc->cctype == AT_CCODE ||
2190 cc->cctype == PH_CCODE)
2191 out_addline_outfile(fp);
2195 print_class_block(Class *c)
2199 gboolean printed_private = FALSE;
2202 out_printf(out, "/* utility types we may need */\n");
2203 if(special_array[SPECIAL_2POINTER])
2204 out_printf(out, "typedef struct { "
2205 "gpointer a; gpointer b; "
2206 "} ___twopointertype;\n");
2207 if(special_array[SPECIAL_3POINTER])
2208 out_printf(out, "typedef struct { "
2209 "gpointer a; gpointer b; "
2211 "} ___threepointertype;\n");
2212 if(special_array[SPECIAL_INT_POINTER])
2213 out_printf(out, "typedef struct { "
2214 "gint a; gpointer b; "
2215 "} ___intpointertype;\n");
2216 out_printf(out, "\n");
2219 out_printf(outh, "\n/*\n"
2220 " * Type checking and casting macros\n"
2222 out_printf(outh, "#define %s\t"
2223 "(%s_get_type())\n",
2224 macrotype, funcbase);
2225 out_printf(outh, "#define %s(obj)\t"
2226 "GTK_CHECK_CAST((obj), %s_get_type(), %s)\n",
2227 macrobase, funcbase, typebase);
2228 out_printf(outh, "#define %s_CONST(obj)\t"
2229 "GTK_CHECK_CAST((obj), %s_get_type(), %s const)\n",
2230 macrobase, funcbase, typebase);
2231 out_printf(outh, "#define %s_CLASS(klass)\t"
2232 "GTK_CHECK_CLASS_CAST((klass), %s_get_type(), %sClass)\n",
2233 macrobase, funcbase, typebase);
2234 out_printf(outh, "#define %s(obj)\t"
2235 "GTK_CHECK_TYPE((obj), %s_get_type ())\n\n",
2237 out_printf(outh, "#ifdef GTK_CHECK_GET_CLASS\n"
2238 "#define %s_GET_CLASS(obj)\t"
2239 "GTK_CHECK_GET_CLASS((obj), %s_get_type(), %sClass)\n",
2240 macrobase, funcbase, typebase);
2241 out_printf(outh, "#else /* !GTK_CHECK_GET_CLASS */\n"
2242 "#define %s_GET_CLASS(obj)\t"
2243 "((%sClass *)GTK_OBJECT(obj)->klass)\n"
2244 "#endif /* GTK_CHECK_GET_CLASS */\n",
2245 macrobase, typebase);
2247 if( ! no_self_alias) {
2248 out_printf(out, "/* self casting macros */\n");
2249 out_printf(out, "#define SELF(x) %s(x)\n", macrobase);
2250 out_printf(out, "#define SELF_CONST(x) %s_CONST(x)\n", macrobase);
2251 out_printf(out, "#define IS_SELF(x) %s(x)\n", macrois);
2252 out_printf(out, "#define TYPE_SELF %s\n", macrotype);
2253 out_printf(out, "#define SELF_CLASS(x) %s_CLASS(x)\n\n",
2255 out_printf(out, "#define SELF_GET_CLASS(x) %s_GET_CLASS(x)\n\n",
2258 out_printf(out, "/* self typedefs */\n");
2259 out_printf(out, "typedef %s Self;\n", typebase);
2260 out_printf(out, "typedef %sClass SelfClass;\n\n", typebase);
2263 out_printf(out, "/* GTK_CLASS_TYPE for 1.2<->1.3/2.0 GTK+ compatibility */\n");
2265 "#ifndef GTK_CLASS_TYPE\n"
2266 "#define GTK_CLASS_TYPE(x) (GTK_OBJECT_CLASS(x)->type)\n"
2267 "#endif /* GTK_CLASS_TYPE */\n\n");
2269 if(privates > 0 || always_private_struct) {
2270 out_printf(outh, "\n/* Private structure type */\n");
2271 out_printf(outh, "typedef struct _%sPrivate %sPrivate;\n",
2272 typebase, typebase);
2274 out_printf(outh, "/* There are no privates, this "
2275 "structure is thus never defined */\n");
2278 out_printf(outh, "\n/*\n"
2279 " * Main object structure\n"
2281 s = replace_sep(c->otype, '_');
2283 out_printf(outh, "#ifndef __TYPEDEF_%s__\n"
2284 "#define __TYPEDEF_%s__\n", s, s);
2286 out_printf(outh, "typedef struct _%s %s;\n"
2287 "#endif\n", typebase, typebase);
2288 out_printf(outh, "struct _%s {\n\t%s __parent__;\n",
2289 typebase, ptypebase);
2290 for(l=c->nodes; l; l=g_list_next(l)) {
2291 static gboolean printed_public = FALSE;
2293 Variable *v = (Variable *)n;
2294 if(n->type == VARIABLE_NODE &&
2295 v->scope == PUBLIC_SCOPE) {
2296 if( ! printed_public) {
2297 out_printf(outh, "\t/*< public >*/\n");
2298 printed_public = TRUE;
2300 put_variable((Variable *)n, outh);
2303 /* put protecteds always AFTER publics */
2304 for(l=c->nodes; l; l=g_list_next(l)) {
2306 Variable *v = (Variable *)n;
2307 if(n->type == VARIABLE_NODE &&
2308 v->scope == PROTECTED_SCOPE) {
2309 if( ! printed_private) {
2310 out_printf(outh, "\t/*< private >*/\n");
2311 printed_private = TRUE;
2313 put_variable((Variable *)n, outh);
2316 if(privates > 0 || always_private_struct) {
2317 if( ! printed_private)
2318 out_printf(outh, "\t/*< private >*/\n");
2319 out_printf(outh, "\t%sPrivate *_priv;\n", typebase);
2321 out_printf(outh, "};\n");
2326 /* if we are to stick this into the private
2327 header, if not stick it directly into the
2334 out_printf(outfp, "struct _%sPrivate {\n",
2336 for(l=c->nodes; l; l=l->next) {
2338 Variable *v = (Variable *)n;
2339 if(n->type == VARIABLE_NODE &&
2340 v->scope == PRIVATE_SCOPE) {
2341 out_addline_infile(outfp, v->line_no);
2342 put_variable(v, outfp);
2345 out_addline_outfile(outfp);
2346 out_printf(outfp, "};\n");
2349 out_printf(outh, "\n/*\n"
2350 " * Class definition\n"
2352 out_printf(outh, "typedef struct _%sClass %sClass;\n",
2353 typebase, typebase);
2355 "struct _%sClass {\n\t%sClass __parent__;\n",
2356 typebase, ptypebase);
2357 for(l = c->nodes; l != NULL; l = l->next) {
2359 if(n->type == METHOD_NODE)
2360 put_vs_method((Method *)n);
2362 /* If BonoboX type class put down the epv */
2363 if (c->bonobo_x_class != NULL) {
2365 "\t/* Bonobo object epv */\n"
2366 "\tPOA_%s__epv _epv;\n",
2369 /* put class scope variables */
2370 for(l = c->nodes; l != NULL; l = l->next) {
2372 Variable *v = (Variable *)n;
2373 if(n->type == VARIABLE_NODE &&
2374 v->scope == CLASS_SCOPE)
2375 put_variable((Variable *)n, outh);
2377 out_printf(outh, "};\n\n");
2379 out_printf(out, "/* here are local prototypes */\n");
2380 if(set_arguments > 0) {
2381 out_printf(out, "static void ___object_set_arg "
2382 "(GtkObject *object, GtkArg *arg, "
2383 "guint arg_id);\n");
2385 if(get_arguments > 0) {
2386 out_printf(out, "static void ___object_get_arg "
2387 "(GtkObject *object, GtkArg *arg, "
2388 "guint arg_id);\n");
2391 out_printf(outh, "\n/*\n"
2392 " * Public methods\n"
2395 if ( ! overrode_get_type) {
2396 out_printf(outh, "GtkType\t%s_get_type\t(void)", funcbase);
2398 out_printf(outh, " G_GNUC_CONST;\n");
2400 out_printf(outh, ";\n");
2404 for(l = c->nodes; l != NULL; l = l->next) {
2406 if(n->type == METHOD_NODE) {
2407 put_pub_method((Method *)n);
2408 put_prot_method((Method *)n);
2409 put_priv_method_prot((Method *)n);
2413 /* this idea is less and less apealing to me */
2415 out_printf (outh, "\n/*\n"
2416 " * Signal connection wrapper macros\n"
2419 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
2420 put_signal_macros (c, TRUE);
2421 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
2422 put_signal_macros (c, FALSE);
2423 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n");
2425 put_signal_macros (c, FALSE);
2429 /* argument wrapping macros */
2430 if(get_arguments > 0 || set_arguments > 0) {
2431 out_printf(outh, "\n/*\n"
2432 " * Argument wrapping macros\n"
2435 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
2436 put_argument_gnu_wrappers(c);
2437 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
2438 put_argument_nongnu_wrappers(c);
2439 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n");
2441 put_argument_nongnu_wrappers(c);
2446 for(l = c->nodes; l != NULL; l = l->next) {
2448 if(n->type == METHOD_NODE)
2449 add_signal_prots((Method *)n);
2455 if ( ! overrode_get_type) {
2456 if (c->bonobo_x_class != NULL)
2457 add_bonobo_x_get_type ();
2462 if(any_method_to_alias(c)) {
2464 out_printf(out, "/* Short form macros */\n");
2465 out_printf(out, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
2466 make_method_gnu_aliases(c);
2467 out_printf(out, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n");
2469 make_method_nongnu_aliases(c);
2472 out_printf(out, "/* a macro for creating a new object of our type */\n");
2474 "#define GET_NEW ((%s *)gtk_type_new(%s_get_type()))\n\n",
2475 typebase, funcbase);
2485 if(set_arguments > 0) {
2486 add_getset_arg(c, TRUE);
2489 if(get_arguments > 0) {
2490 add_getset_arg(c, FALSE);
2493 for(l = c->nodes; l != NULL; l = l->next) {
2495 if(n->type == METHOD_NODE)
2496 put_method((Method *)n);
2499 add_bad_hack_to_avoid_unused_warnings(c);
2503 print_version_macros(void)
2505 int major=0, minor=0, pl=0;
2506 sscanf(VERSION, "%d.%d.%d", &major, &minor, &pl);
2508 out_printf(out, "#define GOB_VERSION_MAJOR %d\n", major);
2509 out_printf(out, "#define GOB_VERSION_MINOR %d\n", minor);
2510 out_printf(out, "#define GOB_VERSION_PATCHLEVEL %d\n\n", pl);
2514 print_file_comments(void)
2518 out_printf(outh, "/* Generated by GOB (v%s)"
2519 " (do not edit directly) */\n\n", VERSION);
2521 out_printf(outph, "/* Generated by GOB (v%s)"
2522 " (do not edit directly) */\n\n", VERSION);
2523 out_printf(out, "/* Generated by GOB (v%s) on %s"
2524 " (do not edit directly) */\n\n",
2525 VERSION, ctime(&curtime));
2527 out_printf(out, "/* End world hunger, donate to the World Food Programme, http://www.wfp.org */\n\n");
2531 print_includes(void)
2533 gboolean found_header;
2536 /* We may need string.h for memset */
2537 if(destructors > 0 &&
2538 ! g_list_find_custom(include_files, "string.h", (GCompareFunc)strcmp)) {
2539 out_printf(out, "#include <string.h> /* memset() */\n\n");
2542 p = g_strconcat(filebase, ".h", NULL);
2543 found_header = TRUE;
2544 if( ! g_list_find_custom(include_files, p, (GCompareFunc)strcmp)) {
2545 out_printf(out, "#include \"%s.h\"\n\n", filebase);
2546 found_header = FALSE;
2550 /* if we are creating a private header see if it was included */
2552 p = g_strconcat(filebase, "-private.h", NULL);
2553 if( ! g_list_find_custom(include_files, p,
2554 (GCompareFunc)strcmp)) {
2555 out_printf(out, "#include \"%s-private.h\"\n\n",
2558 error_printf(GOB_WARN, 0,
2559 "Implicit private header include "
2561 "\tsource file, while public "
2562 "header is at a custom location, "
2564 "\texplicitly include "
2565 "the private header below the "
2573 print_header_prefixes(void)
2577 p = replace_sep(((Class *)class)->otype, '_');
2579 out_printf(outh, "#ifndef __%s_H__\n#define __%s_H__\n\n", p, p);
2581 out_printf(outph, "#ifndef __%s_PRIVATE_H__\n"
2582 "#define __%s_PRIVATE_H__\n\n"
2583 "#include \"%s.h\"\n\n", p, p, filebase);
2586 if( ! no_extern_c) {
2587 out_printf(outh, "#ifdef __cplusplus\n"
2589 "#endif /* __cplusplus */\n\n");
2591 out_printf(outph, "#ifdef __cplusplus\n"
2593 "#endif /* __cplusplus */\n\n");
2598 print_header_postfixes(void)
2601 out_printf(outh, "\n#ifdef __cplusplus\n"
2603 "#endif /* __cplusplus */\n");
2604 out_printf(outh, "\n#endif\n");
2607 out_printf(outph, "\n#ifdef __cplusplus\n"
2609 "#endif /* __cplusplus */\n");
2610 out_printf(outph, "\n#endif\n");
2619 /* print the AT_CCODE blocks */
2620 for(li = nodes; li != NULL; li = li->next) {
2621 Node *node = li->data;
2622 if(node->type == CCODE_NODE) {
2623 CCode *cc = (CCode *)node;
2624 if(cc->cctype == AT_CCODE)
2625 print_ccode_block((CCode *)node);
2631 print_header_top(void)
2635 /* mandatory include */
2636 out_printf(outh, "#include <gtk/gtk.h>\n\n");
2638 /* print the HT_CCODE blocks */
2639 for(li=nodes;li;li=g_list_next(li)) {
2640 Node *node = li->data;
2641 if(node->type == CCODE_NODE) {
2642 CCode *cc = (CCode *)node;
2643 if(cc->cctype == HT_CCODE)
2644 print_ccode_block((CCode *)node);
2650 generate_outfiles(void)
2654 print_file_comments();
2660 print_header_prefixes();
2662 print_version_macros();
2666 for(li=nodes;li;li=g_list_next(li)) {
2667 Node *node = li->data;
2668 if(node->type == CCODE_NODE) {
2669 CCode *cc = (CCode *)node;
2670 if(cc->cctype != HT_CCODE &&
2671 cc->cctype != AT_CCODE)
2672 print_ccode_block((CCode *)node);
2673 } else if(node->type == CLASS_NODE) {
2674 print_class_block((Class *)node);
2676 g_assert_not_reached();
2679 print_header_postfixes();
2685 fprintf(stderr, "Gob version %s\n\n", VERSION);
2686 fprintf(stderr, "gob [options] file.gob\n\n");
2687 fprintf(stderr, "Options:\n"
2688 "\t--help,-h,-? Display this help\n"
2689 "\t--version Display version\n"
2690 "\t--exit-on-warn,-w Exit with an error on warnings\n"
2691 "\t--no-exit-on-warn Don't exit on warnings [default]\n"
2692 "\t--for-cpp Create C++ files\n"
2693 "\t--no-extern-c Never print extern \"C\" into the "
2695 "\t--no-gnu Never use GNU extentions\n"
2696 "\t--no-touch-headers Don't touch headers unless they "
2698 "\t--always-private-header Always create a private header "
2700 "\t even if it would be empty "
2702 "\t--ondemand-private-header Create private header only when "
2704 "\t--no-private-header Don't create a private header, "
2706 "\t structure and protected "
2707 "prototypes inside c file\n"
2708 "\t--always-private-struct Always create a private pointer "
2710 "\t the object structure\n"
2711 "\t--no-write,-n Don't write output files, just "
2713 "\t--no-lines Don't print '#line' to output\n"
2714 "\t--no-self-alias Don't create self type and macro "
2716 "\t--no-kill-underscores Don't remove the leading underscore "
2718 "\t short id names\n");
2722 parse_options(int argc, char *argv[])
2725 int got_file = FALSE;
2726 int no_opts = FALSE;
2730 for(i = 1 ; i < argc; i++) {
2732 argv[i][0] != '-') {
2735 fprintf(stderr, "Specify only one file!\n");
2741 } else if(strcmp(argv[i], "--help")==0) {
2744 } else if(strcmp(argv[i], "--version")==0) {
2745 fprintf(stderr, "Gob version %s\n", VERSION);
2747 } else if(strcmp(argv[i], "--exit-on-warn")==0) {
2748 exit_on_warn = TRUE;
2749 } else if(strcmp(argv[i], "--no-exit-on-warn")==0) {
2750 exit_on_warn = FALSE;
2751 } else if(strcmp(argv[i], "--for-cpp")==0) {
2753 } else if(strcmp(argv[i], "--no-touch-headers")==0) {
2754 no_touch_headers = TRUE;
2755 } else if(strcmp(argv[i], "--ondemand-private-header")==0) {
2756 private_header = PRIVATE_HEADER_ONDEMAND;
2757 } else if(strcmp(argv[i], "--always-private-header")==0) {
2758 private_header = PRIVATE_HEADER_ALWAYS;
2759 } else if(strcmp(argv[i], "--no-private-header")==0) {
2760 private_header = PRIVATE_HEADER_NEVER;
2761 } else if(strcmp(argv[i], "--no-gnu")==0) {
2763 } else if(strcmp(argv[i], "--no-extern-c")==0) {
2765 } else if(strcmp(argv[i], "--no-write")==0) {
2767 } else if(strcmp(argv[i], "--no-lines")==0) {
2769 } else if(strcmp(argv[i], "--no-self-alias")==0) {
2770 no_self_alias = TRUE;
2771 } else if(strcmp(argv[i], "--no-kill-underscores")==0) {
2772 no_kill_underscores = TRUE;
2773 } else if(strcmp(argv[i], "--always-private-struct")==0) {
2774 always_private_struct = TRUE;
2775 } else if(strcmp(argv[i], "--")==0) {
2776 /*further arguments are files*/
2778 } else if(strncmp(argv[i], "--", 2)==0) {
2779 /*unknown long option*/
2780 fprintf(stderr, "Unknown option '%s'!\n", argv[i]);
2784 /*by now we know we have a string starting with
2785 - which is a short option string*/
2787 for(p = argv[i] + 1; *p; p++) {
2801 "Unknown option '%c'!\n", *p);
2810 /* this is a somewhat ugly hack, but it appears to work */
2812 compare_and_move_header(void)
2814 char *hfnew = g_strconcat("#gob#", filebase, ".h#gob#", NULL);
2815 char *hf = g_strconcat(filebase, ".h", NULL);
2817 if(stat(hf, &s) == 0) {
2819 s = g_strdup_printf("cmp '%s' '%s' > /dev/null", hf, hfnew);
2820 if(system(s) == 0) {
2821 if(unlink(hfnew) != 0)
2822 error_printf(GOB_ERROR, 0,
2823 "Can't remove new header file");
2831 error_printf(GOB_ERROR, 0,
2832 "Can't remove old header file");
2834 if(rename(hfnew, hf) != 0)
2835 error_printf(GOB_ERROR, 0,
2836 "Can't rename new header file");
2842 main(int argc, char *argv[])
2844 parse_options(argc, argv);
2847 yyin = fopen(filename, "r");
2849 fprintf(stderr, "Error: can't open file '%s'\n",
2856 /* This is where parsing is done */
2859 g_error("Parsing errors, quitting");
2862 error_print(GOB_ERROR, 0, " no class defined");
2865 exit_on_error = FALSE;
2867 signals = count_signals((Class *)class);
2868 set_arguments = count_set_arguments((Class *)class);
2869 get_arguments = count_get_arguments((Class *)class);
2870 overrides = count_overrides((Class *)class);
2871 privates = count_privates((Class *)class);
2872 protecteds = count_protecteds((Class *)class);
2873 destructors = count_destructors((Class *)class);
2874 initializers = count_initializers((Class *)class);
2875 overrode_get_type = find_get_type((Class *)class);
2878 make_inits((Class *)class);
2879 if(destructors > 0) {
2880 need_destroy = TRUE;
2881 find_destroy((Class *)class);
2884 need_finalize = TRUE;
2885 find_finalize((Class *)class);
2887 check_bad_symbols((Class *)class);
2888 check_duplicate_symbols((Class *)class);
2889 check_duplicate_overrides((Class *)class);
2890 check_duplicate_signals_args((Class *)class);
2891 check_public_new((Class *)class);
2892 check_vararg((Class *)class);
2893 check_firstarg((Class *)class);
2894 check_nonvoidempty((Class *)class);
2895 check_signal_args((Class *)class);
2896 check_argument_types((Class *)class);
2897 check_func_arg_checks((Class *)class);
2899 exit_on_error = TRUE;
2904 any_special = setup_special_array((Class *)class, special_array);
2908 generate_outfiles();
2919 if(no_touch_headers &&
2921 compare_and_move_header();