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_ALWAYS;
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 SELF_CLASS(x) %s_CLASS(x)\n\n",
2254 out_printf(out, "#define SELF_GET_CLASS(x) %s_GET_CLASS(x)\n\n",
2257 out_printf(out, "/* self typedefs */\n");
2258 out_printf(out, "typedef %s Self;\n", typebase);
2259 out_printf(out, "typedef %sClass SelfClass;\n\n", typebase);
2262 out_printf(out, "/* GTK_CLASS_TYPE for 1.2<->1.3/2.0 GTK+ compatibility */\n");
2264 "#ifndef GTK_CLASS_TYPE\n"
2265 "#define GTK_CLASS_TYPE(x) (GTK_OBJECT_CLASS(x)->type)\n"
2266 "#endif /* GTK_CLASS_TYPE */\n\n");
2268 if(privates > 0 || always_private_struct) {
2269 out_printf(outh, "\n/* Private structure type */\n");
2270 out_printf(outh, "typedef struct _%sPrivate %sPrivate;\n",
2271 typebase, typebase);
2273 out_printf(outh, "/* There are no privates, this "
2274 "structure is thus never defined */\n");
2277 out_printf(outh, "\n/*\n"
2278 " * Main object structure\n"
2280 s = replace_sep(c->otype, '_');
2282 out_printf(outh, "#ifndef __TYPEDEF_%s__\n"
2283 "#define __TYPEDEF_%s__\n", s, s);
2285 out_printf(outh, "typedef struct _%s %s;\n"
2286 "#endif\n", typebase, typebase);
2287 out_printf(outh, "struct _%s {\n\t%s __parent__;\n",
2288 typebase, ptypebase);
2289 for(l=c->nodes; l; l=g_list_next(l)) {
2290 static gboolean printed_public = FALSE;
2292 Variable *v = (Variable *)n;
2293 if(n->type == VARIABLE_NODE &&
2294 v->scope == PUBLIC_SCOPE) {
2295 if( ! printed_public) {
2296 out_printf(outh, "\t/*< public >*/\n");
2297 printed_public = TRUE;
2299 put_variable((Variable *)n, outh);
2302 /* put protecteds always AFTER publics */
2303 for(l=c->nodes; l; l=g_list_next(l)) {
2305 Variable *v = (Variable *)n;
2306 if(n->type == VARIABLE_NODE &&
2307 v->scope == PROTECTED_SCOPE) {
2308 if( ! printed_private) {
2309 out_printf(outh, "\t/*< private >*/\n");
2310 printed_private = TRUE;
2312 put_variable((Variable *)n, outh);
2315 if(privates > 0 || always_private_struct) {
2316 if( ! printed_private)
2317 out_printf(outh, "\t/*< private >*/\n");
2318 out_printf(outh, "\t%sPrivate *_priv;\n", typebase);
2320 out_printf(outh, "};\n");
2325 /* if we are to stick this into the private
2326 header, if not stick it directly into the
2333 out_printf(outfp, "struct _%sPrivate {\n",
2335 for(l=c->nodes; l; l=l->next) {
2337 Variable *v = (Variable *)n;
2338 if(n->type == VARIABLE_NODE &&
2339 v->scope == PRIVATE_SCOPE) {
2340 out_addline_infile(outfp, v->line_no);
2341 put_variable(v, outfp);
2344 out_addline_outfile(outfp);
2345 out_printf(outfp, "};\n");
2348 out_printf(outh, "\n/*\n"
2349 " * Class definition\n"
2351 out_printf(outh, "typedef struct _%sClass %sClass;\n",
2352 typebase, typebase);
2354 "struct _%sClass {\n\t%sClass __parent__;\n",
2355 typebase, ptypebase);
2356 for(l = c->nodes; l != NULL; l = l->next) {
2358 if(n->type == METHOD_NODE)
2359 put_vs_method((Method *)n);
2361 /* If BonoboX type class put down the epv */
2362 if (c->bonobo_x_class != NULL) {
2364 "\t/* Bonobo object epv */\n"
2365 "\tPOA_%s__epv _epv;\n",
2368 /* put class scope variables */
2369 for(l = c->nodes; l != NULL; l = l->next) {
2371 Variable *v = (Variable *)n;
2372 if(n->type == VARIABLE_NODE &&
2373 v->scope == CLASS_SCOPE)
2374 put_variable((Variable *)n, outh);
2376 out_printf(outh, "};\n\n");
2378 out_printf(out, "/* here are local prototypes */\n");
2379 if(set_arguments > 0) {
2380 out_printf(out, "static void ___object_set_arg "
2381 "(GtkObject *object, GtkArg *arg, "
2382 "guint arg_id);\n");
2384 if(get_arguments > 0) {
2385 out_printf(out, "static void ___object_get_arg "
2386 "(GtkObject *object, GtkArg *arg, "
2387 "guint arg_id);\n");
2390 out_printf(outh, "\n/*\n"
2391 " * Public methods\n"
2394 if ( ! overrode_get_type) {
2395 out_printf(outh, "GtkType\t%s_get_type\t(void)", funcbase);
2397 out_printf(outh, " G_GNUC_CONST;\n");
2399 out_printf(outh, ";\n");
2403 for(l = c->nodes; l != NULL; l = l->next) {
2405 if(n->type == METHOD_NODE) {
2406 put_pub_method((Method *)n);
2407 put_prot_method((Method *)n);
2408 put_priv_method_prot((Method *)n);
2412 /* this idea is less and less apealing to me */
2414 out_printf (outh, "\n/*\n"
2415 " * Signal connection wrapper macros\n"
2418 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
2419 put_signal_macros (c, TRUE);
2420 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
2421 put_signal_macros (c, FALSE);
2422 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n");
2424 put_signal_macros (c, FALSE);
2428 /* argument wrapping macros */
2429 if(get_arguments > 0 || set_arguments > 0) {
2430 out_printf(outh, "\n/*\n"
2431 " * Argument wrapping macros\n"
2434 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
2435 put_argument_gnu_wrappers(c);
2436 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
2437 put_argument_nongnu_wrappers(c);
2438 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n");
2440 put_argument_nongnu_wrappers(c);
2445 for(l = c->nodes; l != NULL; l = l->next) {
2447 if(n->type == METHOD_NODE)
2448 add_signal_prots((Method *)n);
2454 if ( ! overrode_get_type) {
2455 if (c->bonobo_x_class != NULL)
2456 add_bonobo_x_get_type ();
2461 if(any_method_to_alias(c)) {
2463 out_printf(out, "/* Short form macros */\n");
2464 out_printf(out, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
2465 make_method_gnu_aliases(c);
2466 out_printf(out, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n");
2468 make_method_nongnu_aliases(c);
2471 out_printf(out, "/* a macro for creating a new object of our type */\n");
2473 "#define GET_NEW ((%s *)gtk_type_new(%s_get_type()))\n\n",
2474 typebase, funcbase);
2484 if(set_arguments > 0) {
2485 add_getset_arg(c, TRUE);
2488 if(get_arguments > 0) {
2489 add_getset_arg(c, FALSE);
2492 for(l = c->nodes; l != NULL; l = l->next) {
2494 if(n->type == METHOD_NODE)
2495 put_method((Method *)n);
2498 add_bad_hack_to_avoid_unused_warnings(c);
2502 print_version_macros(void)
2504 int major=0, minor=0, pl=0;
2505 sscanf(VERSION, "%d.%d.%d", &major, &minor, &pl);
2507 out_printf(out, "#define GOB_VERSION_MAJOR %d\n", major);
2508 out_printf(out, "#define GOB_VERSION_MINOR %d\n", minor);
2509 out_printf(out, "#define GOB_VERSION_PATCHLEVEL %d\n\n", pl);
2513 print_file_comments(void)
2517 out_printf(outh, "/* Generated by GOB (v%s)"
2518 " (do not edit directly) */\n\n", VERSION);
2520 out_printf(outph, "/* Generated by GOB (v%s)"
2521 " (do not edit directly) */\n\n", VERSION);
2522 out_printf(out, "/* Generated by GOB (v%s) on %s"
2523 " (do not edit directly) */\n\n",
2524 VERSION, ctime(&curtime));
2526 out_printf(out, "/* End world hunger, donate to the World Food Programme, http://www.wfp.org */\n\n");
2530 print_includes(void)
2532 gboolean found_header;
2535 /* We may need string.h for memset */
2536 if(destructors > 0 &&
2537 ! g_list_find_custom(include_files, "string.h", (GCompareFunc)strcmp)) {
2538 out_printf(out, "#include <string.h> /* memset() */\n\n");
2541 p = g_strconcat(filebase, ".h", NULL);
2542 found_header = TRUE;
2543 if( ! g_list_find_custom(include_files, p, (GCompareFunc)strcmp)) {
2544 out_printf(out, "#include \"%s.h\"\n\n", filebase);
2545 found_header = FALSE;
2549 /* if we are creating a private header see if it was included */
2551 p = g_strconcat(filebase, "-private.h", NULL);
2552 if( ! g_list_find_custom(include_files, p,
2553 (GCompareFunc)strcmp)) {
2554 out_printf(out, "#include \"%s-private.h\"\n\n",
2557 error_printf(GOB_WARN, 0,
2558 "Implicit private header include "
2560 "\tsource file, while public "
2561 "header is at a custom location, "
2563 "\texplicitly include "
2564 "the private header below the "
2572 print_header_prefixes(void)
2576 p = replace_sep(((Class *)class)->otype, '_');
2578 out_printf(outh, "#ifndef __%s_H__\n#define __%s_H__\n\n", p, p);
2580 out_printf(outph, "#ifndef __%s_PRIVATE_H__\n"
2581 "#define __%s_PRIVATE_H__\n\n"
2582 "#include \"%s.h\"\n\n", p, p, filebase);
2585 if( ! no_extern_c) {
2586 out_printf(outh, "#ifdef __cplusplus\n"
2588 "#endif /* __cplusplus */\n\n");
2590 out_printf(outph, "#ifdef __cplusplus\n"
2592 "#endif /* __cplusplus */\n\n");
2597 print_header_postfixes(void)
2600 out_printf(outh, "\n#ifdef __cplusplus\n"
2602 "#endif /* __cplusplus */\n");
2603 out_printf(outh, "\n#endif\n");
2606 out_printf(outph, "\n#ifdef __cplusplus\n"
2608 "#endif /* __cplusplus */\n");
2609 out_printf(outph, "\n#endif\n");
2618 /* print the AT_CCODE blocks */
2619 for(li = nodes; li != NULL; li = li->next) {
2620 Node *node = li->data;
2621 if(node->type == CCODE_NODE) {
2622 CCode *cc = (CCode *)node;
2623 if(cc->cctype == AT_CCODE)
2624 print_ccode_block((CCode *)node);
2630 print_header_top(void)
2634 /* mandatory include */
2635 out_printf(outh, "#include <gtk/gtk.h>\n\n");
2637 /* print the HT_CCODE blocks */
2638 for(li=nodes;li;li=g_list_next(li)) {
2639 Node *node = li->data;
2640 if(node->type == CCODE_NODE) {
2641 CCode *cc = (CCode *)node;
2642 if(cc->cctype == HT_CCODE)
2643 print_ccode_block((CCode *)node);
2649 generate_outfiles(void)
2653 print_file_comments();
2659 print_header_prefixes();
2661 print_version_macros();
2665 for(li=nodes;li;li=g_list_next(li)) {
2666 Node *node = li->data;
2667 if(node->type == CCODE_NODE) {
2668 CCode *cc = (CCode *)node;
2669 if(cc->cctype != HT_CCODE &&
2670 cc->cctype != AT_CCODE)
2671 print_ccode_block((CCode *)node);
2672 } else if(node->type == CLASS_NODE) {
2673 print_class_block((Class *)node);
2675 g_assert_not_reached();
2678 print_header_postfixes();
2684 fprintf(stderr, "Gob version %s\n\n", VERSION);
2685 fprintf(stderr, "gob [options] file.gob\n\n");
2686 fprintf(stderr, "Options:\n"
2687 "\t--help,-h,-? Display this help\n"
2688 "\t--version Display version\n"
2689 "\t--exit-on-warn,-w Exit with an error on warnings\n"
2690 "\t--no-exit-on-warn Don't exit on warnings [default]\n"
2691 "\t--for-cpp Create C++ files\n"
2692 "\t--no-extern-c Never print extern \"C\" into the "
2694 "\t--no-gnu Never use GNU extentions\n"
2695 "\t--no-touch-headers Don't touch headers unless they "
2697 "\t--always-private-header Always create a private header "
2699 "\t even if it would be empty "
2701 "\t--ondemand-private-header Create private header only when "
2703 "\t--no-private-header Don't create a private header, "
2705 "\t structure and protected "
2706 "prototypes inside c file\n"
2707 "\t--always-private-struct Always create a private pointer "
2709 "\t the object structure\n"
2710 "\t--no-write,-n Don't write output files, just "
2712 "\t--no-lines Don't print '#line' to output\n"
2713 "\t--no-self-alias Don't create self type and macro "
2715 "\t--no-kill-underscores Don't remove the leading underscore "
2717 "\t short id names\n");
2721 parse_options(int argc, char *argv[])
2724 int got_file = FALSE;
2725 int no_opts = FALSE;
2729 for(i = 1 ; i < argc; i++) {
2731 argv[i][0] != '-') {
2734 fprintf(stderr, "Specify only one file!\n");
2740 } else if(strcmp(argv[i], "--help")==0) {
2743 } else if(strcmp(argv[i], "--version")==0) {
2744 fprintf(stderr, "Gob version %s\n", VERSION);
2746 } else if(strcmp(argv[i], "--exit-on-warn")==0) {
2747 exit_on_warn = TRUE;
2748 } else if(strcmp(argv[i], "--no-exit-on-warn")==0) {
2749 exit_on_warn = FALSE;
2750 } else if(strcmp(argv[i], "--for-cpp")==0) {
2752 } else if(strcmp(argv[i], "--no-touch-headers")==0) {
2753 no_touch_headers = TRUE;
2754 } else if(strcmp(argv[i], "--ondemand-private-header")==0) {
2755 private_header = PRIVATE_HEADER_ONDEMAND;
2756 } else if(strcmp(argv[i], "--always-private-header")==0) {
2757 private_header = PRIVATE_HEADER_ALWAYS;
2758 } else if(strcmp(argv[i], "--no-private-header")==0) {
2759 private_header = PRIVATE_HEADER_NEVER;
2760 } else if(strcmp(argv[i], "--no-gnu")==0) {
2762 } else if(strcmp(argv[i], "--no-extern-c")==0) {
2764 } else if(strcmp(argv[i], "--no-write")==0) {
2766 } else if(strcmp(argv[i], "--no-lines")==0) {
2768 } else if(strcmp(argv[i], "--no-self-alias")==0) {
2769 no_self_alias = TRUE;
2770 } else if(strcmp(argv[i], "--no-kill-underscores")==0) {
2771 no_kill_underscores = TRUE;
2772 } else if(strcmp(argv[i], "--always-private-struct")==0) {
2773 always_private_struct = TRUE;
2774 } else if(strcmp(argv[i], "--")==0) {
2775 /*further arguments are files*/
2777 } else if(strncmp(argv[i], "--", 2)==0) {
2778 /*unknown long option*/
2779 fprintf(stderr, "Unknown option '%s'!\n", argv[i]);
2783 /*by now we know we have a string starting with
2784 - which is a short option string*/
2786 for(p = argv[i] + 1; *p; p++) {
2800 "Unknown option '%c'!\n", *p);
2809 /* this is a somewhat ugly hack, but it appears to work */
2811 compare_and_move_header(void)
2813 char *hfnew = g_strconcat("#gob#", filebase, ".h#gob#", NULL);
2814 char *hf = g_strconcat(filebase, ".h", NULL);
2816 if(stat(hf, &s) == 0) {
2818 s = g_strdup_printf("cmp '%s' '%s' > /dev/null", hf, hfnew);
2819 if(system(s) == 0) {
2820 if(unlink(hfnew) != 0)
2821 error_printf(GOB_ERROR, 0,
2822 "Can't remove new header file");
2830 error_printf(GOB_ERROR, 0,
2831 "Can't remove old header file");
2833 if(rename(hfnew, hf) != 0)
2834 error_printf(GOB_ERROR, 0,
2835 "Can't rename new header file");
2841 main(int argc, char *argv[])
2843 parse_options(argc, argv);
2846 yyin = fopen(filename, "r");
2848 fprintf(stderr, "Error: can't open file '%s'\n",
2855 /* This is where parsing is done */
2858 g_error("Parsing errors, quitting");
2861 error_print(GOB_ERROR, 0, " no class defined");
2864 exit_on_error = FALSE;
2866 signals = count_signals((Class *)class);
2867 set_arguments = count_set_arguments((Class *)class);
2868 get_arguments = count_get_arguments((Class *)class);
2869 overrides = count_overrides((Class *)class);
2870 privates = count_privates((Class *)class);
2871 protecteds = count_protecteds((Class *)class);
2872 destructors = count_destructors((Class *)class);
2873 initializers = count_initializers((Class *)class);
2874 overrode_get_type = find_get_type((Class *)class);
2877 make_inits((Class *)class);
2878 if(destructors > 0) {
2879 need_destroy = TRUE;
2880 find_destroy((Class *)class);
2883 need_finalize = TRUE;
2884 find_finalize((Class *)class);
2886 check_bad_symbols((Class *)class);
2887 check_duplicate_symbols((Class *)class);
2888 check_duplicate_overrides((Class *)class);
2889 check_duplicate_signals_args((Class *)class);
2890 check_public_new((Class *)class);
2891 check_vararg((Class *)class);
2892 check_firstarg((Class *)class);
2893 check_nonvoidempty((Class *)class);
2894 check_signal_args((Class *)class);
2895 check_argument_types((Class *)class);
2896 check_func_arg_checks((Class *)class);
2898 exit_on_error = TRUE;
2903 any_special = setup_special_array((Class *)class, special_array);
2907 generate_outfiles();
2918 if(no_touch_headers &&
2920 compare_and_move_header();