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 */
71 static gboolean made_aliases = FALSE; /* if we made any shorthand aliases
72 and need the REALLY UGLY HACK to
75 /* the special variable types we need to define */
76 static gboolean special_array[SPECIAL_LAST] = {0};
77 static gboolean any_special = FALSE;
79 static gboolean need_destroy = FALSE;
80 static Method * destroy_handler = NULL;
82 static gboolean need_finalize = FALSE;
83 static Method * finalize_handler = NULL;
90 gboolean no_touch_headers = FALSE;
91 gboolean for_cpp = FALSE;
92 gboolean no_gnu = FALSE;
93 gboolean exit_on_warn = FALSE;
94 gboolean exit_on_error = TRUE;
95 gboolean got_error = FALSE;
96 gint private_header = PRIVATE_HEADER_ALWAYS;
97 gboolean no_extern_c = FALSE;
98 gboolean no_write = FALSE;
99 gboolean no_lines = FALSE;
100 gboolean no_self_alias = FALSE;
101 gboolean no_kill_underscores = FALSE;
102 gboolean always_private_struct = FALSE;
104 int method_unique_id = 1;
109 filebase = replace_sep(((Class *)class)->otype, '-');
112 funcbase = replace_sep(((Class *)class)->otype, '_');
115 pfuncbase = replace_sep(((Class *)class)->ptype, '_');
116 g_strdown(pfuncbase);
118 macrobase = replace_sep(((Class *)class)->otype, '_');
121 macrois = make_pre_macro(((Class *)class)->otype, "IS");
122 macrotype = make_pre_macro(((Class *)class)->otype, "TYPE");
124 typebase = remove_sep(((Class *)class)->otype);
126 ptypebase = remove_sep(((Class *)class)->ptype);
130 get_type(Type *t, gboolean postfix_to_stars)
137 s = remove_sep(t->name);
138 gs = g_string_new(s);
142 if(postfix_to_stars) {
144 /*XXX: this is ugly perhaps we can do this whole postfix thing
145 in a nicer way, we just count the number of '[' s and from
146 that we deduce the number of dimensions, so that we can print
148 for(p=t->postfix; p && *p; p++)
149 if(*p == '[') extra++;
151 g_string_append_c(gs, ' ');
154 g_string_append(gs, t->pointer);
155 for(i=0; i < extra; i++)
156 g_string_append_c(gs, '*');
157 g_string_append_c(gs, ' ');
161 g_string_free(gs, FALSE);
166 get_gtk_doc(char *id)
173 val = g_hash_table_lookup(gtk_doc_hash, id);
175 return g_strdup_printf("/**\n * %s_%s:\n%s **/\n",
176 funcbase, get_real_id(id), val);
177 val = g_hash_table_lookup(gtk_doc_hash, get_real_id(id));
179 return g_strdup_printf("/**\n * %s_%s:\n%s **/\n",
180 funcbase, get_real_id(id), val);
185 print_type(FILE *fp, Type *t, gboolean postfix_to_stars)
189 s = get_type(t, postfix_to_stars);
190 out_printf(fp, "%s", s);
196 print_method(FILE *fp, char *typeprefix, char *nameprefix,
198 char *namepostfix, char *postfix, Method *m,
199 gboolean one_arg_per_line,
200 gboolean no_funcbase,
201 gboolean kill_underscore)
206 out_printf(fp, "%s", typeprefix);
207 print_type(fp, m->mtype, TRUE);
210 id = get_real_id(m->id);
215 out_printf(fp, "%s%s%s%s(",
216 nameprefix, subnameprefix, id, namepostfix);
218 out_printf(fp, "%s%s_%s%s%s(",
219 nameprefix, funcbase, subnameprefix, id,
223 for(li=m->args; li; li=g_list_next(li)) {
224 FuncArg *arg = li->data;
225 print_type(fp, arg->atype, FALSE);
227 out_printf(fp, "%s%s,%s", arg->name,
229 arg->atype->postfix:"",
230 one_arg_per_line?"\n\t\t\t\t\t":" ");
232 out_printf(fp, "%s%s", arg->name,
234 arg->atype->postfix:"");
237 out_printf(fp, ",%s...",
238 one_arg_per_line?"\n\t\t\t\t\t":" ");
240 out_printf(fp, "void");
242 out_printf(fp, ")%s", postfix);
246 any_method_to_alias(Class *c)
250 for(li=c->nodes;li;li=g_list_next(li)) {
251 Node *node = li->data;
252 if(node->type == METHOD_NODE) {
253 Method *m = (Method *)node;
255 if(m->method == INIT_METHOD ||
256 m->method == CLASS_INIT_METHOD ||
257 m->method == OVERRIDE_METHOD)
268 make_method_gnu_aliases(Class *c)
272 for(li=c->nodes;li;li=g_list_next(li)) {
273 Node *node = li->data;
274 if(node->type == METHOD_NODE) {
275 Method *m = (Method *)node;
277 if(m->method == INIT_METHOD ||
278 m->method == CLASS_INIT_METHOD ||
279 m->method == OVERRIDE_METHOD)
282 /* in C++ mode don't alias new */
283 if(for_cpp && strcmp(m->id, "new")==0)
286 out_printf(out, "static const typeof(&%s_%s) %s "
287 "__attribute__ ((__unused__)) "
288 "= %s_%s;\n", funcbase, get_real_id(m->id),
289 m->id, funcbase, get_real_id(m->id));
290 out_printf(out, "#define %s(args...) "
291 "%s_%s(##args)\n", m->id,
292 funcbase, get_real_id(m->id));
298 make_method_nongnu_aliases(Class *c)
302 for(li=c->nodes; li; li=g_list_next(li)) {
303 Node *node = li->data;
304 if(node->type == METHOD_NODE) {
305 Method *m = (Method *)node;
307 if(m->method == INIT_METHOD ||
308 m->method == CLASS_INIT_METHOD ||
309 m->method == OVERRIDE_METHOD)
312 /* in C++ mode don't alias new */
313 if(for_cpp && strcmp(m->id, "new")==0)
316 print_method(out, "static ", "(* ", "", ") ", "",
317 m, FALSE, TRUE, FALSE);
318 out_printf(out, " = %s_%s;\n", funcbase,
327 add_bad_hack_to_avoid_unused_warnings(Class *c)
331 /* if we haven't had any methods, just return */
336 out_printf(out, "\n\n#if (!defined __GNUC__) || (defined __GNUC__ && defined __STRICT_ANSI__)\n");
338 "/*REALLY BAD HACK\n"
339 " This is to avoid unused warnings if you don't call\n"
340 " some method. I need to find a better way to do\n"
341 " this, not needed in GCC since we use some gcc\n"
342 " extentions to make saner, faster code */\n"
344 "___%s_really_bad_hack_to_avoid_warnings(void)\n"
346 for(li=c->nodes;li;li=g_list_next(li)) {
347 Node *node = li->data;
348 if(node->type == METHOD_NODE) {
349 Method *m = (Method *)node;
351 if(m->method == INIT_METHOD ||
352 m->method == CLASS_INIT_METHOD ||
353 m->method == OVERRIDE_METHOD)
356 /* in C++ mode we don't alias new */
357 if(for_cpp && strcmp(m->id, "new")==0)
360 out_printf(out, "\t((void (*)(void))%s)();\n", m->id);
363 out_printf(out, "\t___%s_really_bad_hack_to_avoid_warnings();\n",
366 out_printf(out, "}\n#endif /* !__GNUC__ || (__GNUC__ && __STRICT_ANSI__) */\n\n");
368 out_printf(out, "}\n\n");
372 put_variable(Variable *v, FILE *fp)
374 out_printf(fp, "\t");
375 print_type(fp, v->vtype, FALSE);
376 out_printf(fp, "%s%s;", v->id,
378 v->vtype->postfix:"");
379 if(v->scope == PROTECTED_SCOPE)
380 out_printf(fp, " /* protected */");
381 out_printf(fp, "\n");
385 put_vs_method(Method *m)
387 if(m->method != SIGNAL_LAST_METHOD &&
388 m->method != SIGNAL_FIRST_METHOD &&
389 m->method != VIRTUAL_METHOD)
392 /* if a signal mark it as such */
393 if(m->method != VIRTUAL_METHOD)
394 print_method(outh, "\t/*signal*/", "(* ", "", ") ", ";\n",
395 m, FALSE, TRUE, TRUE);
397 print_method(outh, "\t", "(* ", "", ") ", ";\n",
398 m, FALSE, TRUE, TRUE);
402 put_pub_method(Method *m)
404 if(m->scope != PUBLIC_SCOPE)
407 print_method(outh, "", "\t", "", "\t", ";\n", m, TRUE, FALSE, TRUE);
410 /* I'm starting not to like this idea */
413 put_signal_connect(Method *m)
415 if(m->method != SIGNAL_LAST_METHOD &&
416 m->method != SIGNAL_FIRST_METHOD)
419 out_printf(outh, "guint \t%s_%s__connect_full\t(%s *object,\n"
420 "\t\t\t\t\tconst char *name,\n"
421 "\t\t\t\t\tGtkSignalFunc func,\n"
422 "\t\t\t\t\tGtkCallbackMarshal marshal,\n"
423 "\t\t\t\t\tgpointer data,\n"
424 "\t\t\t\t\tGtkDestroyNotify destroy_func,\n"
425 "\t\t\t\t\tgboolean object_signal,\n"
426 "\t\t\t\t\tgboolean after);\n",
427 funcbase, m->id, typebase);
429 out_printf(outh, "#define %s_%s__connect(object,name,func,data) "
430 "%s_%s__connect_full((object),(name),(func),NULL,"
431 "(data),NULL,FALSE,FALSE)\n",
432 funcbase, m->id, funcbase, m->id);
433 out_printf(outh, "#define %s_%s__connect_after(object,name,func,data) "
434 "%s__connect_%s_full((object),(name),(func),NULL,"
435 "(data),NULL,FALSE,TRUE)\n",
436 funcbase, m->id, funcbase, m->id);
438 out_printf(outh, "guint \t%s_%s__connect_while_alive\t(%s *object,\n"
439 "\t\t\t\t\tconst char *name,\n"
440 "\t\t\t\t\tGtkSignalFunc func,\n"
441 "\t\t\t\t\tgpointer data,\n"
442 "\t\t\t\t\tGtkObject *alive_object);\n\n",
443 funcbase, m->id, typebase);
449 put_prot_method(Method *m)
451 if(m->scope != PROTECTED_SCOPE)
455 print_method(outph, "", "\t", "", "\t", ";\n",
456 m, FALSE, FALSE, TRUE);
458 print_method(out, "", "\t", "", "\t", ";\n",
459 m, FALSE, FALSE, TRUE);
463 put_priv_method_prot(Method *m)
465 if(m->method == SIGNAL_LAST_METHOD ||
466 m->method == SIGNAL_FIRST_METHOD ||
467 m->method == VIRTUAL_METHOD) {
470 "static ", "___real_", "", " ", ";\n",
471 m, FALSE, FALSE, TRUE);
473 /* no else, here, it might still have a private prototype, it's not
476 if((m->method == OVERRIDE_METHOD &&
479 char *s = g_strdup_printf("___%x_", (guint)m->unique_id);
480 print_method(out, "static ", s, "", " ",
481 no_gnu?";\n":" G_GNUC_UNUSED;\n",
482 m, FALSE, FALSE, FALSE);
484 } else if(m->scope == PRIVATE_SCOPE ||
485 m->method == INIT_METHOD ||
486 m->method == CLASS_INIT_METHOD)
487 print_method(out, "static ", "", "", " ",
488 no_gnu?";\n":" G_GNUC_UNUSED;\n",
489 m, FALSE, FALSE, TRUE);
493 make_func_arg(char *typename, int is_class, char *name)
500 tn = g_strconcat(typename, ":Class", NULL);
502 tn = g_strdup(typename);
504 type = new_type(tn, g_strdup("*"), NULL);
505 node = new_funcarg((Type *)type, name, NULL);
506 return g_list_prepend(NULL, node);
510 make_inits(Class *cl)
512 int got_class_init = FALSE;
513 int got_init = FALSE;
516 for(li=cl->nodes;li;li=g_list_next(li)) {
518 if(n->type == METHOD_NODE) {
519 Method *m = (Method *)n;
520 if(m->method == INIT_METHOD) {
522 error_print(GOB_ERROR, m->line_no, "init defined more then once");
524 } else if(m->method == CLASS_INIT_METHOD) {
526 error_print(GOB_ERROR, m->line_no, "class_init defined more then once");
527 got_class_init = TRUE;
531 if(!got_class_init) {
532 node = new_method(NO_SCOPE, CLASS_INIT_METHOD,
533 (Type *)new_type(g_strdup("void"),
535 NULL, NULL, NULL, g_strdup("class_init"),
536 make_func_arg(cl->otype, TRUE, g_strdup("c")),
537 NULL, NULL, NULL, 0, 0, FALSE,
539 cl->nodes = g_list_prepend(cl->nodes, node);
542 node = new_method(NO_SCOPE, INIT_METHOD,
543 (Type *)new_type(g_strdup("void"),
545 NULL, NULL, NULL, g_strdup("init"),
546 make_func_arg(cl->otype, FALSE, g_strdup("o")),
547 NULL, NULL, NULL, 0, 0, FALSE,
549 cl->nodes = g_list_prepend(cl->nodes, node);
554 find_destroy(Class *cl)
558 destroy_handler = NULL;
559 for(li=cl->nodes;li;li=g_list_next(li)) {
561 if(n->type == METHOD_NODE) {
562 Method *m = (Method *)n;
563 if(m->method == OVERRIDE_METHOD &&
564 strcmp(m->id, "destroy")==0) {
565 if(strcmp(m->otype, "Gtk:Object") != 0) {
566 error_print(GOB_ERROR, m->line_no,
567 "destroy method override "
568 "of class other then "
571 if(g_list_length(m->args) != 1) {
572 error_print(GOB_ERROR, m->line_no,
573 "destroy method override "
574 "with more then one "
585 find_finalize(Class *cl)
589 finalize_handler = NULL;
590 for(li=cl->nodes;li;li=g_list_next(li)) {
592 if(n->type == METHOD_NODE) {
593 Method *m = (Method *)n;
594 if(m->method == OVERRIDE_METHOD &&
595 strcmp(m->id, "finalize")==0) {
596 if(strcmp(m->otype, "Gtk:Object") != 0 &&
597 strcmp(m->otype, "G:Object") != 0) {
598 error_print(GOB_ERROR, m->line_no,
599 "finalize method override "
600 "of class other then "
601 "Gtk:Object (or G:Object"
604 if(g_list_length(m->args) != 1) {
605 error_print(GOB_ERROR, m->line_no,
606 "finalize method override "
607 "with more then one "
610 finalize_handler = m;
618 /* hash of method -> name of signal prototype */
619 static GHashTable *marsh = NULL;
621 /* list of methods with different signal prototypes,
622 we check this list if we can use a signal prototype of a
623 previous signal method, there are only uniques here */
624 static GList *eq_signal_methods = NULL;
626 /* compare a list of strings */
628 is_list_equal(GList *a, GList *b)
630 for(;a && b; a=a->next, b=b->next) {
631 if(strcmp(a->data, b->data)!=0) {
635 /* the the lists were different length */
642 find_same_type_signal(Method *m)
645 for(li=eq_signal_methods;li;li=li->next) {
646 Method *mm = li->data;
647 if(is_list_equal(mm->gtktypes, m->gtktypes))
654 print_signal_marsal_args(Method *m)
656 if(strcmp(m->gtktypes->next->data, "NONE")!=0) {
659 for(i=0, li=m->gtktypes->next;li;
660 i++, li=g_list_next(li)) {
662 out_printf(out, ",\n\t\tGTK_VALUE_%s(args[%d])",
663 (char *)li->data, i);
665 out_printf(out, ",\n\t\t(%s)"
666 "GTK_VALUE_%s(args[%d])",
667 get_cast(li->data, FALSE),
668 (char *)li->data, i);
672 out_printf(out, ",\n\t\tfunc_data);\n}\n\n");
677 add_signal_prots(Method *m)
684 if(m->method != SIGNAL_LAST_METHOD &&
685 m->method != SIGNAL_FIRST_METHOD)
689 marsh = g_hash_table_new(NULL, NULL);
691 if(strcmp(m->gtktypes->data, "NONE")==0 &&
692 strcmp(m->gtktypes->next->data, "NONE")==0)
695 /* if we already did a signal prototype just use that */
696 mm = find_same_type_signal(m);
698 s = g_hash_table_lookup(marsh, mm);
699 g_hash_table_insert(marsh, m, s);
703 s = g_strdup_printf("Sig%d", sig++);
705 g_hash_table_insert(marsh, m, s);
706 eq_signal_methods = g_list_prepend(eq_signal_methods, m);
708 /* we know that we'll know all the gtktypes (so get_cast can't fail) */
709 out_printf(out, "\ntypedef %s (*___%s) (%s *, ",
710 get_cast(m->gtktypes->data, FALSE), s, typebase);
712 if(strcmp(m->gtktypes->next->data, "NONE")!=0) {
713 for(li=m->gtktypes->next; li; li=g_list_next(li))
714 out_printf(out, "%s, ", get_cast(li->data, FALSE));
716 out_printf(out, "gpointer);\n");
718 out_printf(out, "\nstatic void\n"
719 "___marshal_%s (GtkObject * object,\n"
720 "\tGtkSignalFunc func,\n"
721 "\tgpointer func_data,\n"
725 if(strcmp(m->gtktypes->data, "NONE")==0) {
726 out_printf(out, "\t___%s rfunc;\n\n"
727 "\trfunc = (___%s)func;\n\n"
728 "\t(*rfunc)((%s *)object", s, s, typebase);
730 const char *retcast = get_cast(m->gtktypes->data, FALSE);
734 "\trfunc = (___%s)func;\n\n"
735 "\tretval = GTK_RETLOC_%s(args[%d]);\n\n"
736 "\t*retval = (*rfunc)((%s *)object",
737 s, retcast, s, (char *)m->gtktypes->data,
738 g_list_length(m->gtktypes)-1, typebase);
740 print_signal_marsal_args(m);
748 out_printf(out, "\n");
750 out_printf(out, "enum {\n");
751 for(li=c->nodes;li;li=g_list_next(li)) {
753 if(n->type == METHOD_NODE) {
754 Method *m = (Method *)n;
755 if(m->method == SIGNAL_LAST_METHOD ||
756 m->method == SIGNAL_FIRST_METHOD) {
757 char *s = g_strdup(get_real_id(m->id));
759 out_printf(out, "\t%s_SIGNAL,\n", s);
764 out_printf(out, "\tLAST_SIGNAL\n};\n\n");
766 if(set_arguments > 0 || get_arguments > 0) {
767 out_printf(out, "enum {\n\tARG_0");
768 for(li=c->nodes;li;li=g_list_next(li)) {
770 if(n->type == ARGUMENT_NODE) {
771 Argument *a = (Argument *)n;
772 char *s = g_strdup(a->name);
774 out_printf(out, ",\n\tARG_%s", s);
778 out_printf(out, "\n};\n\n");
783 "static guint object_signals[LAST_SIGNAL] = {0};\n\n");
785 out_printf(out, "/* pointer to the class of our parent */\n");
786 out_printf(out, "static %sClass *parent_class = NULL;\n\n", ptypebase);
792 char *chunk_size = ((Class*)class)->chunk_size;
794 out_printf(out, "guint\n"
795 "%s_get_type (void)\n"
797 "\tstatic guint type = 0;\n\n"
799 "\t\tstatic const GtkTypeInfo info = {\n"
801 "\t\t\tsizeof (%s),\n"
802 "\t\t\tsizeof (%sClass),\n"
803 "\t\t\t(GtkClassInitFunc) %s_class_init,\n"
804 "\t\t\t(GtkObjectInitFunc) %s_init,\n"
805 "\t\t\t/* reserved_1 */ NULL,\n"
806 "\t\t\t/* reserved_2 */ NULL,\n"
807 "\t\t\t(GtkClassInitFunc) NULL\n"
809 "\t\ttype = gtk_type_unique (%s_get_type(), &info);\n",
810 funcbase, typebase, typebase, typebase,
811 funcbase, funcbase, pfuncbase);
813 out_printf(out, "#if %s > 0\n"
814 "\t\tgtk_type_set_chunk_alloc(type,%s);\n"
816 chunk_size, chunk_size);
818 out_printf(out,"\t}\n\n"
824 add_overrides(Class *c, char *oname, gboolean did_base_obj)
830 done = g_hash_table_new(g_str_hash, g_str_equal);
832 s = g_strdup("GtkObject"); /* This was already done */
833 g_hash_table_insert(done, s, s);
834 s = g_strdup("GObject"); /* This was probably already done as well (if using Gtk/Glib 1.3/2.0) */
835 g_hash_table_insert(done, s, s);
837 for(li=c->nodes; li; li=g_list_next(li)) {
840 Method *m = (Method *)n;
841 if(n->type != METHOD_NODE ||
842 m->method != OVERRIDE_METHOD)
845 s = remove_sep(m->otype);
847 if(g_hash_table_lookup(done, s)) {
851 g_hash_table_insert(done, s, s);
853 f = replace_sep(m->otype, '_');
856 out_printf(out, "\t%sClass *%s_class = (%sClass *)%s;\n",
861 g_hash_table_foreach(done, (GHFunc)g_free, NULL);
862 g_hash_table_destroy(done);
866 make_run_signal_flags(Method *m, gboolean last)
880 gs = g_string_new(NULL);
883 g_string_assign(gs, "GTK_RUN_LAST");
885 g_string_assign(gs, "GTK_RUN_FIRST");
887 if(m->scope == PUBLIC_SCOPE)
888 g_string_append(gs, " | GTK_RUN_ACTION");
890 for(li = m->flags; li; li = li->next) {
891 char *flag = li->data;
893 for(i=0;flags[i];i++) {
894 if(strcmp(flags[i], flag)==0)
897 /* if we haven't found it in our list */
899 error_printf(GOB_WARN, m->line_no,
900 "Unknown flag '%s' used, "
901 "perhaps it was misspelled",
904 g_string_sprintfa(gs, " | GTK_RUN_%s", flag);
909 g_string_free(gs, FALSE);
916 add_signals(Class *c)
920 out_printf(out, "\n");
921 for(li=c->nodes;li;li=g_list_next(li)) {
923 char *mar, *sig, *flags;
924 gboolean is_none, last = FALSE;
925 Method *m = (Method *)n;
927 if(n->type != METHOD_NODE ||
928 (m->method != SIGNAL_FIRST_METHOD &&
929 m->method != SIGNAL_LAST_METHOD))
932 if(m->method == SIGNAL_FIRST_METHOD)
937 if(g_hash_table_lookup(marsh, m))
938 mar = g_strconcat("___marshal_",
939 (char *)g_hash_table_lookup(marsh, m),
942 mar = g_strdup("gtk_signal_default_marshaller");
944 is_none = (strcmp(m->gtktypes->next->data, "NONE")==0);
946 sig = g_strdup(get_real_id(m->id));
948 flags = make_run_signal_flags(m, last);
949 out_printf(out, "\tobject_signals[%s_SIGNAL] =\n"
950 "\t\tgtk_signal_new (\"%s\",\n"
951 "\t\t\t(GtkSignalRunType)(%s),\n"
952 "\t\t\tGTK_CLASS_TYPE(gtk_object_class),\n"
953 "\t\t\tGTK_SIGNAL_OFFSET (%sClass, %s),\n"
955 "\t\t\tGTK_TYPE_%s, %d",
956 sig, get_real_id(m->id),
958 typebase, get_real_id(m->id), mar,
959 (char *)m->gtktypes->data,
960 is_none ? 0 : g_list_length(m->gtktypes->next));
967 for(l = m->gtktypes->next; l != NULL; l = l->next)
968 out_printf(out, ",\n\t\t\tGTK_TYPE_%s",
972 out_printf(out, ");\n");
974 if(strcmp(m->gtktypes->data, "NONE") != 0 ||
978 out_printf(out, "\tif(");
979 if(strcmp(m->gtktypes->data, "NONE") != 0) {
980 out_printf(out, "%s sizeof(", sep);
981 print_type(out, m->mtype, FALSE);
982 out_printf(out, "%s",
984 m->mtype->postfix : "");
985 out_printf(out, ") != sizeof(%s)",
986 get_cast(m->gtktypes->data, FALSE));
991 for(al = m->args->next, gl = m->gtktypes->next;
992 al != NULL && gl != NULL;
993 al = al->next, gl = gl->next) {
994 FuncArg *arg = al->data;
995 char *gtkarg = gl->data;
997 out_printf(out, "%ssizeof(", sep);
998 print_type(out, arg->atype, FALSE);
999 out_printf(out, "%s",
1000 arg->atype->postfix ?
1001 arg->atype->postfix : "");
1002 out_printf(out, ") != sizeof(%s)",
1003 get_cast(gtkarg, FALSE));
1007 out_printf(out, ") {\n"
1008 "\t\tg_error(\"%s line %d: Type mismatch "
1009 "of \\\"%s\\\" signal signature\");\n"
1011 filename, m->line_no, get_real_id(m->id));
1015 out_printf(out, "\tgtk_object_class_add_signals (gtk_object_class,\n"
1016 "\t\tobject_signals, LAST_SIGNAL);\n\n");
1020 set_def_handlers(Class *c, char *oname)
1023 gboolean set_line = FALSE;
1025 out_printf(out, "\n");
1026 for(li = c->nodes; li; li = g_list_next(li)) {
1028 Method *m = (Method *)n;
1030 if(n->type != METHOD_NODE ||
1031 (m->method != SIGNAL_FIRST_METHOD &&
1032 m->method != SIGNAL_LAST_METHOD &&
1033 m->method != VIRTUAL_METHOD &&
1034 m->method != OVERRIDE_METHOD))
1037 if(m->line_no > 0 && m->cbuf) {
1038 out_addline_infile(out, m->line_no);
1040 } else if(set_line) {
1041 out_addline_outfile(out);
1046 if(m->method == OVERRIDE_METHOD) {
1048 s = replace_sep(m->otype, '_');
1053 strcmp(get_real_id(m->id), "destroy") == 0)
1054 out_printf(out, "\tgtk_object_class->destroy "
1056 else if(need_finalize &&
1058 strcmp(get_real_id(m->id), "finalize") == 0)
1060 "#ifdef G_OBJECT_CLASS\n"
1061 "\tg_object_class->finalize = ___finalize;\n"
1062 "#else /* !G_OBJECT_CLASS */\n"
1063 "\tgtk_object_class->finalize = ___finalize;\n"
1064 "#endif /* G_OBJECT_CLASS */\n");
1067 "\t%s_class->%s = ___%x_%s_%s;\n",
1068 s, get_real_id(m->id), (guint)m->unique_id,
1069 funcbase, get_real_id(m->id));
1071 out_printf(out, "\t%s_class->%s = NULL;\n",
1072 s, get_real_id(m->id));
1075 out_printf(out, "\t%s->%s = ___real_%s_%s;\n",
1076 oname, get_real_id(m->id),
1077 funcbase, get_real_id(m->id));
1079 out_printf(out, "\t%s->%s = NULL;\n",
1080 oname, get_real_id(m->id));
1084 out_addline_outfile(out);
1088 make_arguments(Class *c)
1091 char *argflags[] = {
1099 out_printf(out, "\n");
1100 for(li=c->nodes;li;li=g_list_next(li)) {
1106 if(n->type != ARGUMENT_NODE)
1111 if(a->get && a->set)
1112 flags = g_string_new("GTK_ARG_READWRITE");
1114 flags = g_string_new("GTK_ARG_READABLE");
1116 flags = g_string_new("GTK_ARG_WRITABLE");
1118 g_assert(a->get || a->set);
1120 for(l=a->flags;l;l=g_list_next(l)) {
1121 char *flag = l->data;
1123 if(strcmp(flag, "READWRITE")==0 ||
1124 strcmp(flag, "READABLE")==0 ||
1125 strcmp(flag, "WRITABLE")==0) {
1126 error_print(GOB_WARN, a->line_no,
1127 "READWRITE, READABLE and "
1128 "WRITABLE argument flags are "
1129 "set automatically");
1132 for(i = 0; argflags[i]; i++) {
1133 if(strcmp(argflags[i], flag)==0)
1136 /* if we haven't found it in our list */
1137 if( ! argflags[i]) {
1138 error_printf(GOB_WARN, a->line_no,
1139 "Unknown flag '%s' used, "
1140 "perhaps it was misspelled", flag);
1142 g_string_sprintfa(flags, " | GTK_ARG_%s", flag);
1145 s = g_strdup(a->name);
1147 out_printf(out, "\tgtk_object_add_arg_type(\"%s::%s\",\n"
1148 "\t\tGTK_TYPE_%s,\n"
1151 typebase, a->name, a->gtktype, flags->str, s);
1153 g_string_free(flags, TRUE);
1156 out_printf(out, "\n");
1157 if(get_arguments > 0)
1158 out_printf(out, "\tgtk_object_class->get_arg = ___object_get_arg;\n");
1159 if(set_arguments > 0)
1160 out_printf(out, "\tgtk_object_class->set_arg = ___object_set_arg;\n");
1164 print_initializer(Method *m, Variable *v)
1168 if(v->initializer == NULL)
1171 if(v->scope == PRIVATE_SCOPE)
1172 root = g_strconcat(((FuncArg *)m->args->data)->name,
1175 root = g_strdup(((FuncArg *)m->args->data)->name);
1177 if(v->initializer_line > 0)
1178 out_addline_infile(out, v->initializer_line);
1180 out_printf(out, "\t%s->%s = %s;\n",
1181 root, v->id, v->initializer);
1183 if(v->initializer_line > 0)
1184 out_addline_outfile(out);
1190 print_destructor(Variable *v)
1194 if(v->destructor == NULL)
1197 if(v->scope == PRIVATE_SCOPE)
1198 root = "self->_priv";
1202 if(v->destructor_simple) {
1203 if(v->destructor_line > 0)
1204 out_addline_infile(out, v->destructor_line);
1206 out_printf(out, "\tif(%s->%s) { "
1207 "((*(void (*)(void *))%s)) (%s->%s); "
1208 "%s->%s = NULL; }\n",
1209 root, v->id, v->destructor, root, v->id,
1212 if(v->destructor_line > 0)
1213 out_addline_outfile(out);
1215 out_printf(out, "#define VAR (%s->%s)\n", root, v->id);
1216 out_printf(out, "\t{\n");
1217 if(v->destructor_line > 0)
1218 out_addline_infile(out, v->destructor_line);
1220 out_printf(out, "\t%s}\n", v->destructor);
1222 if(v->destructor_line > 0)
1223 out_addline_outfile(out);
1224 out_printf(out, "\tmemset(&VAR, 0, sizeof(VAR));\n");
1225 out_printf(out, "#undef VAR\n");
1230 add_destroy(Class *c)
1232 out_printf(out, "\nstatic void\n"
1233 "___destroy(GtkObject *obj_self)\n"
1236 "#define __GOB_FUNCTION__ \"%s::destroy\"\n",
1239 if(destructors > 0) {
1240 out_printf(out, "\t%s *self = %s (obj_self);\n",
1241 typebase, macrobase);
1244 if(destroy_handler) {
1245 /* so we get possible bad argument warning */
1246 if(destroy_handler->line_no > 0)
1247 out_addline_infile(out, destroy_handler->line_no);
1248 out_printf(out, "\t___%x_%s_destroy(obj_self);\n",
1249 (guint)destroy_handler->unique_id, funcbase);
1250 if(destroy_handler->line_no > 0)
1251 out_addline_outfile(out);
1254 "\tif(GTK_OBJECT_CLASS(parent_class)->destroy) \\\n"
1255 "\t\t(* GTK_OBJECT_CLASS(parent_class)->destroy)(obj_self);\n");
1258 if(destructors > 0) {
1260 for(li = ((Class *)class)->nodes;
1264 Variable *v = (Variable *)n;
1265 if(n->type == VARIABLE_NODE &&
1266 v->scope != CLASS_SCOPE)
1267 print_destructor(v);
1271 out_printf(out, "\treturn;\n");
1273 out_printf(out, "\tself = NULL;\n");
1274 out_printf(out, "}\n"
1275 "#undef __GOB_FUNCTION__\n\n");
1279 add_finalize(Class *c)
1281 /* Sort of a hack to make it work with gtk+ 1.3/2.0 */
1283 "\n#ifdef G_OBJECT_CLASS\n"
1285 "___finalize(GObject *obj_self)\n"
1286 "#else /* !G_OBJECT_CLASS */\n"
1288 "___finalize(GtkObject *obj_self)\n"
1289 "#endif /* G_OBJECT_CLASS */\n"
1292 "#define __GOB_FUNCTION__ \"%s::finalize\"\n",
1296 out_printf(out, "\t%s *self = %s (obj_self);\n",
1297 typebase, macrobase);
1298 out_printf(out, "\tgpointer priv = self->_priv;\n");
1301 if(finalize_handler) {
1302 /* so we get possible bad argument warning */
1303 if(finalize_handler->line_no > 0)
1304 out_addline_infile(out, finalize_handler->line_no);
1305 out_printf(out, "\t___%x_%s_finalize(obj_self);\n",
1306 (guint)finalize_handler->unique_id, funcbase);
1307 if(finalize_handler->line_no > 0)
1308 out_addline_outfile(out);
1310 /* Sort of a hack to make it work with gtk+ 1.3/2.0 */
1312 "#ifdef G_OBJECT_CLASS\n"
1313 "\tif(G_OBJECT_CLASS(parent_class)->finalize) \\\n"
1314 "\t\t(* G_OBJECT_CLASS(parent_class)->finalize)(obj_self);\n"
1315 "#else /* !G_OBJECT_CLASS */\n"
1316 "\tif(GTK_OBJECT_CLASS(parent_class)->finalize) \\\n"
1317 "\t\t(* GTK_OBJECT_CLASS(parent_class)->finalize)(obj_self);\n"
1318 "#endif /* G_OBJECT_CLASS */\n");
1322 out_printf(out, "\tg_free(priv);\n");
1325 out_printf(out, "}\n"
1326 "#undef __GOB_FUNCTION__\n\n");
1333 for(li=c->nodes;li;li=g_list_next(li)) {
1337 gboolean add_unused_class = FALSE;
1339 if(n->type != METHOD_NODE)
1342 if(m->method == INIT_METHOD) {
1344 out_addline_infile(out, m->line_no);
1345 print_method(out, "static ", "\n", "", " ", "\n",
1346 m, FALSE, FALSE, TRUE);
1348 out_addline_outfile(out);
1349 out_printf(out, "{\n"
1350 "#define __GOB_FUNCTION__ \"%s::init\"\n",
1353 out_printf(out, "\t%s->_priv = "
1354 "g_new0 (%sPrivate, 1);\n",
1355 ((FuncArg *)m->args->data)->name,
1357 } else if(always_private_struct) {
1358 out_printf(out, "\t%s->_priv = NULL;\n",
1359 ((FuncArg *)m->args->data)->name);
1361 if(initializers > 0) {
1363 for(li = ((Class *)class)->nodes;
1367 Variable *v = (Variable *)n;
1368 if(n->type != VARIABLE_NODE ||
1369 v->scope == CLASS_SCOPE)
1371 print_initializer(m, v);
1374 } else if(m->method == CLASS_INIT_METHOD) {
1375 gboolean did_base_obj = FALSE;
1378 out_addline_infile(out, m->line_no);
1379 print_method(out, "static ", "\n", "", " ", "\n",
1380 m, FALSE, FALSE, TRUE);
1382 out_addline_outfile(out);
1383 out_printf(out, "{\n"
1384 "#define __GOB_FUNCTION__ \"%s::class_init\"\n",
1387 set_arguments > 0 ||
1388 get_arguments > 0 ||
1391 add_unused_class = TRUE;
1393 "\tGtkObjectClass *"
1394 "gtk_object_class = "
1395 "(GtkObjectClass*) %s;\n",
1396 ((FuncArg *)m->args->data)->name);
1398 "#ifdef G_OBJECT_CLASS\n"
1401 "(GObjectClass*) %s;\n"
1402 "#endif /* G_OBJECT_CLASS */\n",
1403 ((FuncArg *)m->args->data)->name);
1404 did_base_obj = TRUE;
1409 ((FuncArg *)m->args->data)->name,
1412 if(initializers > 0) {
1414 for(li = ((Class *)class)->nodes;
1418 Variable *v = (Variable *)n;
1419 if(n->type == VARIABLE_NODE &&
1420 v->scope == CLASS_SCOPE)
1421 print_initializer(m, v);
1425 out_printf(out, "\n\tparent_class = ");
1427 out_printf(out, "(%sClass *)", ptypebase);
1428 out_printf(out, "gtk_type_class (%s_get_type ());\n",
1434 set_def_handlers(c, ((FuncArg *)m->args->data)->name);
1436 /* if there are no handlers for these things, we
1437 * need to set them up here */
1438 if(need_destroy && !destroy_handler)
1439 out_printf(out, "\tgtk_object_class->destroy "
1441 if(need_finalize && !finalize_handler)
1443 "#ifdef G_OBJECT_CLASS\n"
1444 "\tg_object_class->finalize = ___finalize;\n"
1445 "#else /* !G_OBJECT_CLASS */\n"
1446 "\tgtk_object_class->finalize = ___finalize;\n"
1447 "#endif /* G_OBJECT_CLASS */\n");
1449 if(get_arguments > 0 || set_arguments > 0)
1456 out_printf(out, " {\n");
1457 out_addline_infile(out, m->ccode_line);
1458 out_printf(out, "%s\n", m->cbuf);
1459 out_addline_outfile(out);
1460 out_printf(out, " }\n");
1462 out_printf(out, "\treturn;\n");
1465 ((FuncArg *)m->args->data)->name);
1466 if(add_unused_class) {
1468 "\tgtk_object_class = NULL;\n"
1469 "#ifdef G_OBJECT_CLASS\n"
1470 "\tg_object_class = NULL;\n"
1471 "#endif /* G_OBJECT_CLASS */\n");
1473 out_printf(out, "}\n"
1474 "#undef __GOB_FUNCTION__\n");
1479 add_getset_arg(Class *c, gboolean is_set)
1482 out_printf(out, "\nstatic void\n"
1483 "___object_%s_arg (GtkObject *object,\n"
1486 "#define __GOB_FUNCTION__ \"%s::%s_arg\"\n"
1489 "\tself = %s (object);\n\n"
1490 "\tswitch (arg_id) {\n",
1491 is_set ? "set" : "get",
1492 c->otype, is_set ? "set" : "get",
1493 typebase, macrobase);
1495 for(li=c->nodes;li;li=g_list_next(li)) {
1501 if(n->type != ARGUMENT_NODE)
1506 line_no = a->set_line;
1509 line_no = a->get_line;
1513 s = g_strdup(a->name);
1515 out_printf(out, "\tcase ARG_%s:\n", s);
1516 if(is_set && a->atype) {
1517 char *cast = get_type(a->atype, TRUE);
1518 if(no_gnu || for_cpp) {
1519 out_printf(out, "#define ARG "
1520 "((%s)GTK_VALUE_%s(*arg))\n",
1523 out_printf(out, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
1524 if(strcmp(a->gtktype, "OBJECT")==0) {
1525 out_printf(out, "#define ARG "
1527 "GTK_VALUE_POINTER(*arg); "
1531 out_printf(out, "#define ARG "
1533 "GTK_VALUE_%s(*arg); "
1537 out_printf(out, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
1538 out_printf(out, "#define ARG "
1539 "((%s)GTK_VALUE_%s(*arg))\n",
1541 out_printf(out, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n");
1543 out_printf(out, "\t\t{\n");
1545 } else if(!is_set && strcmp(a->gtktype, "OBJECT")==0) {
1547 "#define ARG (GTK_VALUE_POINTER(*arg))\n"
1551 "#define ARG (GTK_VALUE_%s(*arg))\n"
1557 out_addline_infile(out, line_no);
1558 out_printf(out, "%s\n", cbuf);
1560 out_addline_outfile(out);
1561 out_printf(out, "\t\t}\n\t\tbreak;\n"
1564 out_printf(out, "\tdefault:\n\t\tbreak;\n\t}\n"
1565 "\treturn;\n\tself = NULL;\n\targ = NULL;\n}\n"
1566 "#undef __GOB_FUNCTION__\n");
1570 print_checks(Method *m, FuncArg *fa)
1574 gboolean checked_null = FALSE;
1575 is_void = (strcmp(m->mtype->name, "void")==0 &&
1576 m->mtype->pointer == NULL);
1578 for(li = fa->checks; li; li = g_list_next(li)) {
1579 Check *ch = li->data;
1581 /* point to the method prot in .gob for failed checks */
1583 out_addline_infile(out, m->line_no);
1585 out_printf(out, "\tg_return_if_fail (");
1587 out_printf(out, "\tg_return_val_if_fail (");
1588 switch(ch->chtype) {
1590 out_printf(out, "%s != NULL", fa->name);
1591 checked_null = TRUE;
1594 s = make_pre_macro(fa->atype->name, "IS");
1596 out_printf(out, "%s (%s)", s, fa->name);
1598 /* if not check null, null may be valid */
1599 out_printf(out, "!(%s) || %s (%s)", fa->name,
1604 out_printf(out, "%s < %s", fa->name, ch->number);
1607 out_printf(out, "%s > %s", fa->name, ch->number);
1610 out_printf(out, "%s <= %s", fa->name, ch->number);
1613 out_printf(out, "%s >= %s", fa->name, ch->number);
1616 out_printf(out, "%s == %s", fa->name, ch->number);
1619 out_printf(out, "%s != %s", fa->name, ch->number);
1623 out_printf(out, ");\n");
1625 out_printf(out, ", (");
1626 print_type(out, m->mtype, TRUE);
1627 out_printf(out, ")%s);\n",
1628 m->onerror?m->onerror:"0");
1634 print_preconditions(Method *m)
1638 for(li=m->args;li;li=g_list_next(li)) {
1639 FuncArg *fa = li->data;
1641 print_checks(m, fa);
1644 out_addline_outfile(out);
1648 print_method_body(Method *m, int pre)
1650 out_printf(out, "{\n"
1651 "#define __GOB_FUNCTION__ \"%s::%s\"\n",
1652 ((Class *)class)->otype,
1653 get_real_id(m->id));
1655 print_preconditions(m);
1657 /* Note: the trailing }'s are on one line, this is so
1658 that we get the no return warning correctly and point to
1659 the correct line in the .gob file, yes this is slightly
1660 ugly in the .c file, but that is not supposed to be
1661 human readable anyway. */
1663 out_printf(out, "{\n");
1665 out_addline_infile(out, m->ccode_line);
1666 out_printf(out, "\t%s}", m->cbuf);
1669 /* Note, there is no \n between the last } and this } so that
1670 * errors/warnings reported on the end of the body get pointed to the
1671 * right line in the .gob source */
1672 out_printf(out, "}\n");
1675 out_addline_outfile(out);
1676 out_printf(out, "#undef __GOB_FUNCTION__\n");
1680 put_signal_args(Method *m)
1684 for(ali = m->gtktypes->next, li=m->args->next;
1686 li=li->next, ali=ali->next) {
1687 FuncArg *fa = li->data;
1688 const char *cast = get_cast(ali->data, FALSE);
1689 /* we should have already proved before that
1690 the we know all the types */
1693 out_printf(out, ",\n\t\t(%s)%s", cast,
1699 get_arg_names_for_macro(Method *m)
1703 GString *gs = g_string_new(NULL);
1705 for(li=m->args;li;li=g_list_next(li)) {
1706 FuncArg *arg = li->data;
1707 g_string_sprintfa(gs, "%s___%s", p, arg->name);
1711 g_string_free(gs, FALSE);
1716 put_method(Method *m)
1718 char *s, *args, *doc;
1720 is_void = (strcmp(m->mtype->name, "void")==0 &&
1721 m->mtype->pointer == NULL);
1722 out_printf(out, "\n");
1723 if(m->method != OVERRIDE_METHOD) {
1724 doc = get_gtk_doc(m->id);
1726 out_printf(out, "%s", doc);
1731 case REGULAR_METHOD:
1733 out_addline_infile(out, m->line_no);
1734 if(m->scope == PRIVATE_SCOPE)
1735 print_method(out, "static ", "\n", "", " ", "\n",
1736 m, FALSE, FALSE, TRUE);
1737 else /* PUBLIC, PROTECTED */
1738 print_method(out, "", "\n", "", " ", "\n",
1739 m, FALSE, FALSE, TRUE);
1740 print_method_body(m, TRUE);
1741 /* the outfile line was added above */
1743 case SIGNAL_FIRST_METHOD:
1744 case SIGNAL_LAST_METHOD:
1746 out_addline_infile(out, m->line_no);
1747 if(m->scope == PRIVATE_SCOPE)
1748 print_method(out, "static ", "\n", "", " ", "\n",
1749 m, FALSE, FALSE, TRUE);
1750 else /* PUBLIC, PROTECTED */
1751 print_method(out, "", "\n", "", " ", "\n",
1752 m, FALSE, FALSE, TRUE);
1753 out_addline_outfile(out);
1754 out_printf(out, "{\n");
1755 s = g_strdup(get_real_id(m->id));
1757 if(strcmp(m->mtype->name, "void") == 0 &&
1758 m->mtype->pointer == NULL) {
1759 print_preconditions(m);
1760 if(((FuncArg *)m->args->data)->name)
1761 out_printf(out, "\tgtk_signal_emit (GTK_OBJECT (%s),\n"
1762 "\t\tobject_signals[%s_SIGNAL]",
1763 ((FuncArg *)m->args->data)->name, s);
1765 out_printf(out, ");\n}\n");
1767 out_printf(out, "\t");
1768 print_type(out, m->mtype, TRUE);
1769 out_printf(out, "return_val = (");
1770 print_type(out, m->mtype, TRUE);
1772 out_printf(out, ")(%s);\n", m->defreturn);
1774 out_printf(out, ")(%s);\n", m->onerror);
1776 out_printf(out, ")(0);\n");
1777 print_preconditions(m);
1778 out_printf(out, "\tgtk_signal_emit (GTK_OBJECT (%s),\n"
1779 "\t\tobject_signals[%s_SIGNAL]",
1780 ((FuncArg *)m->args->data)->name, s);
1782 out_printf(out, ",\n\t\t&return_val);\n"
1783 "\treturn return_val;\n}\n");
1789 out_addline_infile(out, m->line_no);
1790 print_method(out, "static ", "\n___real_", "", " ", "\n",
1791 m, FALSE, FALSE, TRUE);
1792 print_method_body(m, FALSE);
1793 /* the outfile line was added above */
1795 case VIRTUAL_METHOD:
1797 out_addline_infile(out, m->line_no);
1798 if(m->scope==PRIVATE_SCOPE)
1799 print_method(out, "static ", "\n", "", " ", "\n",
1800 m, FALSE, FALSE, TRUE);
1801 else /* PUBLIC, PROTECTED */
1802 print_method(out, "", "\n", "", " ", "\n",
1803 m, FALSE, FALSE, TRUE);
1804 out_addline_outfile(out);
1805 out_printf(out, "{\n"
1806 "\t%sClass *klass;\n", typebase);
1807 print_preconditions(m);
1808 out_printf(out, "\tklass = %s_GET_CLASS(%s);\n\n"
1809 "\tif(klass->%s)\n",
1810 macrobase, ((FuncArg *)m->args->data)->name,
1811 get_real_id(m->id));
1812 if(strcmp(m->mtype->name, "void") == 0 &&
1813 m->mtype->pointer == NULL) {
1815 out_printf(out, "\t\t(*klass->%s)(%s",
1817 ((FuncArg *)m->args->data)->name);
1818 for(li=m->args->next;li;li=g_list_next(li)) {
1819 FuncArg *fa = li->data;
1820 out_printf(out, ",%s", fa->name);
1822 out_printf(out, ");\n}\n");
1825 out_printf(out, "\t\treturn (*klass->%s)(%s",
1827 ((FuncArg *)m->args->data)->name);
1828 for(li=m->args->next;li;li=g_list_next(li)) {
1829 FuncArg *fa = li->data;
1830 out_printf(out, ",%s", fa->name);
1832 out_printf(out, ");\n"
1835 print_type(out, m->mtype, TRUE);
1837 out_printf(out, ")(%s);\n}\n", m->defreturn);
1839 out_printf(out, ")(%s);\n}\n", m->onerror);
1841 out_printf(out, ")(0);\n}\n");
1847 out_addline_infile(out, m->line_no);
1848 print_method(out, "static ", "\n___real_", "", " ", "\n",
1849 m, FALSE, FALSE, TRUE);
1850 print_method_body(m, FALSE);
1851 /* the outfile line was added above */
1853 case OVERRIDE_METHOD:
1857 out_addline_infile(out, m->line_no);
1858 s = g_strdup_printf("\n___%x_", (guint)m->unique_id);
1859 print_method(out, "static ", s, "", " ", "\n",
1860 m, FALSE, FALSE, FALSE);
1862 out_addline_outfile(out);
1863 s = replace_sep(m->otype, '_');
1865 args = get_arg_names_for_macro(m);
1867 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
1868 "\t{ if(%s_CLASS(parent_class)->%s) \\\n"
1869 "\t\t(* %s_CLASS(parent_class)->%s)(%s); }\n",
1870 args, s, get_real_id(m->id), s, get_real_id(m->id), args);
1872 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
1873 "\t((%s_CLASS(parent_class)->%s)? \\\n"
1874 "\t\t(* %s_CLASS(parent_class)->%s)(%s): \\\n"
1876 args, s, get_real_id(m->id), s, get_real_id(m->id), args);
1877 out_printf(out, "(");
1878 print_type(out, m->mtype, TRUE);
1879 out_printf(out, ")%s))\n",
1880 m->onerror?m->onerror:"0");
1884 print_method_body(m, TRUE);
1885 /* the outfile line was added above */
1886 out_printf(out, "#undef PARENT_HANDLER\n");
1896 char *outfile, *outfileh, *outfileph;
1899 outfile = g_strconcat(filebase, ".c", NULL);
1901 outfile = g_strconcat(filebase, ".cc", NULL);
1902 if(no_touch_headers)
1903 outfileh = g_strconcat("#gob#", filebase, ".h#gob#", NULL);
1905 outfileh = g_strconcat(filebase, ".h", NULL);
1907 if((privates > 0 || protecteds > 0 ||
1908 private_header == PRIVATE_HEADER_ALWAYS) &&
1909 private_header != PRIVATE_HEADER_NEVER)
1910 outfileph = g_strconcat(filebase, "-private.h", NULL);
1916 devnull = fopen("/dev/null", "w");
1918 g_error("Cannot open null device");
1924 out = fopen(outfile, "w");
1926 g_error("Cannot open outfile: %s", outfile);
1928 outh = fopen(outfileh, "w");
1930 g_error("Cannot open outfile: %s", outfileh);
1932 outph = fopen(outfileph, "w");
1934 g_error("Cannot open outfile: %s", outfileh);
1940 put_argument_nongnu_wrappers(Class *c)
1944 if(get_arguments < 0 && set_arguments < 0)
1947 for(li=c->nodes;li;li=g_list_next(li)) {
1949 Argument *a = (Argument *)n;
1953 if(n->type != ARGUMENT_NODE)
1956 aname = g_strdup(a->name);
1960 cast = get_type(a->atype, TRUE);
1962 cast = g_strdup(get_cast(a->gtktype, TRUE));
1966 out_printf(outh, "#define %s_ARG_%s(arg) \t"
1967 "\"%s\",(%s)(arg)\n",
1968 macrobase, aname, a->name, cast);
1970 out_printf(outh, "#define %s_GET_ARG_%s(arg)\t"
1971 "\"%s\",(%s*)(arg)\n",
1972 macrobase, aname, a->name, cast);
1975 out_printf(outh, "#define %s_ARG_%s(arg) \t"
1977 macrobase, aname, a->name);
1979 out_printf(outh, "#define %s_GET_ARG_%s(arg)\t"
1981 macrobase, aname, a->name);
1989 put_argument_gnu_wrappers(Class *c)
1993 if(get_arguments < 0 && set_arguments < 0)
1996 for(li=c->nodes;li;li=g_list_next(li)) {
1998 Argument *a = (Argument *)n;
2001 if(n->type != ARGUMENT_NODE)
2003 s = g_strdup(a->name);
2006 cast = get_type(a->atype, TRUE);
2008 cast = g_strdup(get_cast(a->gtktype, TRUE));
2011 out_printf(outh, "#define %s_ARG_%s(arg) \t"
2012 "\"%s\",({%sz = (arg); z;})\n",
2013 macrobase, s, a->name, cast);
2015 out_printf(outh, "#define %s_GET_ARG_%s(arg)\t"
2016 "\"%s\",({%s*z = (arg); z;})\n",
2017 macrobase, s, a->name, cast);
2020 out_printf(outh, "#define %s_ARG_%s(arg) \t"
2022 macrobase, s, a->name);
2024 out_printf(outh, "#define %s_GET_ARG_%s(arg)\t"
2026 macrobase, s, a->name);
2034 print_ccode_block(CCode *cc)
2037 switch(cc->cctype) {
2039 /* HT code is printed exactly like normal header
2040 code but is printed before */
2043 out_printf(fp, "\n");
2046 /* AT code is printed exactly like normal 'all'
2047 code but is printed before */
2050 out_printf(outph, "\n");
2051 out_printf(outph, "%s\n", cc->cbuf);
2052 out_addline_infile(outph, cc->line_no);
2053 out_addline_outfile(outph);
2055 out_printf(outh, "\n");
2056 out_printf(outh, "%s\n", cc->cbuf);
2058 out_printf(fp, "\n");
2059 out_addline_infile(fp, cc->line_no);
2064 out_printf(fp, "\n");
2065 out_addline_infile(fp, cc->line_no);
2072 out_printf(fp, "\n");
2073 out_addline_infile(fp, cc->line_no);
2076 out_printf(fp, "%s\n", cc->cbuf);
2077 if(cc->cctype == C_CCODE ||
2078 cc->cctype == A_CCODE ||
2079 cc->cctype == AT_CCODE ||
2080 cc->cctype == PH_CCODE)
2081 out_addline_outfile(fp);
2085 print_class_block(Class *c)
2089 gboolean printed_private = FALSE;
2092 out_printf(out, "/* utility types we may need */\n");
2093 if(special_array[SPECIAL_2POINTER])
2094 out_printf(out, "typedef struct { "
2095 "gpointer a; gpointer b; "
2096 "} ___twopointertype;\n");
2097 if(special_array[SPECIAL_3POINTER])
2098 out_printf(out, "typedef struct { "
2099 "gpointer a; gpointer b; "
2101 "} ___threepointertype;\n");
2102 if(special_array[SPECIAL_INT_POINTER])
2103 out_printf(out, "typedef struct { "
2104 "gint a; gpointer b; "
2105 "} ___intpointertype;\n");
2106 out_printf(out, "\n");
2109 out_printf(outh, "\n/*\n"
2110 " * Type checking and casting macros\n"
2112 out_printf(outh, "#define %s\t"
2113 "(%s_get_type())\n",
2114 macrotype, funcbase);
2115 out_printf(outh, "#define %s(obj)\t"
2116 "GTK_CHECK_CAST((obj), %s_get_type(), %s)\n",
2117 macrobase, funcbase, typebase);
2118 out_printf(outh, "#define %s_CONST(obj)\t"
2119 "GTK_CHECK_CAST((obj), %s_get_type(), %s const)\n",
2120 macrobase, funcbase, typebase);
2121 out_printf(outh, "#define %s_CLASS(klass)\t"
2122 "GTK_CHECK_CLASS_CAST((klass), %s_get_type(), %sClass)\n",
2123 macrobase, funcbase, typebase);
2124 out_printf(outh, "#define %s(obj)\t"
2125 "GTK_CHECK_TYPE((obj), %s_get_type ())\n\n",
2127 out_printf(outh, "#ifdef GTK_CHECK_GET_CLASS\n"
2128 "#define %s_GET_CLASS(obj)\t"
2129 "GTK_CHECK_GET_CLASS((obj), %s_get_type(), %sClass)\n",
2130 macrobase, funcbase, typebase);
2131 out_printf(outh, "#else /* !GTK_CHECK_GET_CLASS */\n"
2132 "#define %s_GET_CLASS(obj)\t"
2133 "((%sClass *)GTK_OBJECT(obj)->klass)\n"
2134 "#endif /* GTK_CHECK_GET_CLASS */\n",
2135 macrobase, typebase);
2137 if( ! no_self_alias) {
2138 out_printf(out, "/* self casting macros */\n");
2139 out_printf(out, "#define SELF(x) %s(x)\n", macrobase);
2140 out_printf(out, "#define SELF_CONST(x) %s_CONST(x)\n", macrobase);
2141 out_printf(out, "#define IS_SELF(x) %s(x)\n", macrois);
2142 out_printf(out, "#define SELF_CLASS(x) %s_CLASS(x)\n\n",
2144 out_printf(out, "#define SELF_GET_CLASS(x) %s_GET_CLASS(x)\n\n",
2147 out_printf(out, "/* self typedefs */\n");
2148 out_printf(out, "typedef %s Self;\n", typebase);
2149 out_printf(out, "typedef %sClass SelfClass;\n\n", typebase);
2152 out_printf(out, "/* GTK_CLASS_TYPE for 1.2<->1.3/2.0 GTK+ compatibility */\n");
2154 "#ifndef GTK_CLASS_TYPE\n"
2155 "#define GTK_CLASS_TYPE(x) (GTK_OBJECT_CLASS(x)->type)\n"
2156 "#endif /* GTK_CLASS_TYPE */\n\n");
2158 if(privates > 0 || always_private_struct) {
2159 out_printf(outh, "\n/* Private structure type */\n");
2160 out_printf(outh, "typedef struct _%sPrivate %sPrivate;\n",
2161 typebase, typebase);
2163 out_printf(outh, "/* There are no privates, this "
2164 "structure is thus never defined */\n");
2167 out_printf(outh, "\n/*\n"
2168 " * Main object structure\n"
2170 s = replace_sep(c->otype, '_');
2172 out_printf(outh, "#ifndef __TYPEDEF_%s__\n"
2173 "#define __TYPEDEF_%s__\n", s, s);
2175 out_printf(outh, "typedef struct _%s %s;\n"
2176 "#endif\n", typebase, typebase);
2177 out_printf(outh, "struct _%s {\n\t%s __parent__;\n",
2178 typebase, ptypebase);
2179 for(l=c->nodes; l; l=g_list_next(l)) {
2180 static gboolean printed_public = FALSE;
2182 Variable *v = (Variable *)n;
2183 if(n->type == VARIABLE_NODE &&
2184 v->scope == PUBLIC_SCOPE) {
2185 if( ! printed_public) {
2186 out_printf(outh, "\t/*< public >*/\n");
2187 printed_public = TRUE;
2189 put_variable((Variable *)n, outh);
2192 /* put protecteds always AFTER publics */
2193 for(l=c->nodes; l; l=g_list_next(l)) {
2195 Variable *v = (Variable *)n;
2196 if(n->type == VARIABLE_NODE &&
2197 v->scope == PROTECTED_SCOPE) {
2198 if( ! printed_private) {
2199 out_printf(outh, "\t/*< private >*/\n");
2200 printed_private = TRUE;
2202 put_variable((Variable *)n, outh);
2205 if(privates > 0 || always_private_struct) {
2206 if( ! printed_private)
2207 out_printf(outh, "\t/*< private >*/\n");
2208 out_printf(outh, "\t%sPrivate *_priv;\n", typebase);
2210 out_printf(outh, "};\n");
2215 /* if we are to stick this into the private
2216 header, if not stick it directly into the
2223 out_printf(outfp, "struct _%sPrivate {\n",
2225 for(l=c->nodes; l; l=l->next) {
2227 Variable *v = (Variable *)n;
2228 if(n->type == VARIABLE_NODE &&
2229 v->scope == PRIVATE_SCOPE) {
2230 out_addline_infile(outfp, v->line_no);
2231 put_variable(v, outfp);
2234 out_addline_outfile(outfp);
2235 out_printf(outfp, "};\n");
2238 out_printf(outh, "\n/*\n"
2239 " * Class definition\n"
2241 out_printf(outh, "typedef struct _%sClass %sClass;\n",
2242 typebase, typebase);
2244 "struct _%sClass {\n\t%sClass __parent__;\n",
2245 typebase, ptypebase);
2246 for(l = c->nodes; l != NULL; l = l->next) {
2248 if(n->type == METHOD_NODE)
2249 put_vs_method((Method *)n);
2251 /* put class scope variables */
2252 for(l = c->nodes; l != NULL; l = l->next) {
2254 Variable *v = (Variable *)n;
2255 if(n->type == VARIABLE_NODE &&
2256 v->scope == CLASS_SCOPE)
2257 put_variable((Variable *)n, outh);
2259 out_printf(outh, "};\n\n");
2261 out_printf(out, "/* here are local prototypes */\n");
2262 if(set_arguments > 0) {
2263 out_printf(out, "static void ___object_set_arg "
2264 "(GtkObject *object, GtkArg *arg, "
2265 "guint arg_id);\n");
2267 if(get_arguments > 0) {
2268 out_printf(out, "static void ___object_get_arg "
2269 "(GtkObject *object, GtkArg *arg, "
2270 "guint arg_id);\n");
2273 out_printf(outh, "\n/*\n"
2274 " * Public methods\n"
2277 out_printf(outh, "guint\t%s_get_type\t(void);\n", funcbase);
2278 for(l = c->nodes; l != NULL; l = l->next) {
2280 if(n->type == METHOD_NODE) {
2281 put_pub_method((Method *)n);
2282 put_prot_method((Method *)n);
2283 put_priv_method_prot((Method *)n);
2287 /* this idea is less and less apealing to me */
2289 if(!no_signal_connect) {
2291 out_printf(outh, "\n/*\n"
2292 " * Signal connection methods\n"
2296 for(l=c->nodes;l;l=g_list_next(l)) {
2298 if(n->type == METHOD_NODE)
2299 put_signal_connect((Method *)n);
2305 /* argument wrapping macros */
2306 if(get_arguments > 0 || set_arguments > 0) {
2308 out_printf(outh, "\n/*\n"
2309 " * Argument wrapping macros\n"
2311 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
2312 put_argument_gnu_wrappers(c);
2313 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
2314 put_argument_nongnu_wrappers(c);
2315 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n");
2317 out_printf(outh, "\n/*\n"
2318 " * Argument wrapping macros\n"
2320 put_argument_nongnu_wrappers(c);
2325 for(l = c->nodes; l != NULL; l = l->next) {
2327 if(n->type == METHOD_NODE)
2328 add_signal_prots((Method *)n);
2336 if(any_method_to_alias(c)) {
2338 make_method_nongnu_aliases(c);
2340 out_printf(out, "\n#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
2341 make_method_gnu_aliases(c);
2342 out_printf(out, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
2343 make_method_nongnu_aliases(c);
2344 out_printf(out, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n");
2348 out_printf(out, "/* a macro for creating a new object of our type */\n");
2350 "#define GET_NEW ((%s *)gtk_type_new(%s_get_type()))\n\n",
2351 typebase, funcbase);
2361 if(set_arguments > 0) {
2362 add_getset_arg(c, TRUE);
2365 if(get_arguments > 0) {
2366 add_getset_arg(c, FALSE);
2369 for(l = c->nodes; l != NULL; l = l->next) {
2371 if(n->type == METHOD_NODE)
2372 put_method((Method *)n);
2375 add_bad_hack_to_avoid_unused_warnings(c);
2379 print_version_macros(void)
2381 int major=0, minor=0, pl=0;
2382 sscanf(VERSION, "%d.%d.%d", &major, &minor, &pl);
2384 out_printf(out, "#define GOB_VERSION_MAJOR %d\n", major);
2385 out_printf(out, "#define GOB_VERSION_MINOR %d\n", minor);
2386 out_printf(out, "#define GOB_VERSION_PATCHLEVEL %d\n\n", pl);
2390 print_file_comments(void)
2394 out_printf(outh, "/* Generated by GOB (v%s)"
2395 " (do not edit directly) */\n\n", VERSION);
2397 out_printf(outph, "/* Generated by GOB (v%s)"
2398 " (do not edit directly) */\n\n", VERSION);
2399 out_printf(out, "/* Generated by GOB (v%s) on %s"
2400 " (do not edit directly) */\n\n",
2401 VERSION, ctime(&curtime));
2405 print_includes(void)
2407 gboolean found_header;
2410 /* We may need string.h for memset */
2411 if(destructors > 0 &&
2412 ! g_list_find_custom(include_files, "string.h", (GCompareFunc)strcmp)) {
2413 out_printf(out, "#include <string.h> /* memset() */\n\n");
2416 p = g_strconcat(filebase, ".h", NULL);
2417 found_header = TRUE;
2418 if( ! g_list_find_custom(include_files, p, (GCompareFunc)strcmp)) {
2419 out_printf(out, "#include \"%s.h\"\n\n", filebase);
2420 found_header = FALSE;
2424 /* if we are creating a private header see if it was included */
2426 p = g_strconcat(filebase, "-private.h", NULL);
2427 if( ! g_list_find_custom(include_files, p,
2428 (GCompareFunc)strcmp)) {
2429 out_printf(out, "#include \"%s-private.h\"\n\n",
2432 error_printf(GOB_WARN, 0,
2433 "Implicit private header include "
2435 "\tsource file, while public "
2436 "header is at a custom location, "
2438 "\texplicitly include "
2439 "the private header below the "
2447 print_header_prefixes(void)
2451 p = replace_sep(((Class *)class)->otype, '_');
2453 out_printf(outh, "#ifndef __%s_H__\n#define __%s_H__\n\n", p, p);
2455 out_printf(outph, "#ifndef __%s_PRIVATE_H__\n"
2456 "#define __%s_PRIVATE_H__\n\n"
2457 "#include \"%s.h\"\n\n", p, p, filebase);
2460 if( ! no_extern_c) {
2461 out_printf(outh, "#ifdef __cplusplus\n"
2463 "#endif /* __cplusplus */\n\n");
2465 out_printf(outph, "#ifdef __cplusplus\n"
2467 "#endif /* __cplusplus */\n\n");
2472 print_header_postfixes(void)
2475 out_printf(outh, "\n#ifdef __cplusplus\n"
2477 "#endif /* __cplusplus */\n");
2478 out_printf(outh, "\n#endif\n");
2481 out_printf(outph, "\n#ifdef __cplusplus\n"
2483 "#endif /* __cplusplus */\n");
2484 out_printf(outph, "\n#endif\n");
2493 /* print the AT_CCODE blocks */
2494 for(li = nodes; li != NULL; li = li->next) {
2495 Node *node = li->data;
2496 if(node->type == CCODE_NODE) {
2497 CCode *cc = (CCode *)node;
2498 if(cc->cctype == AT_CCODE)
2499 print_ccode_block((CCode *)node);
2505 print_header_top(void)
2509 /* mandatory include */
2510 out_printf(outh, "#include <gtk/gtk.h>\n\n");
2512 /* print the HT_CCODE blocks */
2513 for(li=nodes;li;li=g_list_next(li)) {
2514 Node *node = li->data;
2515 if(node->type == CCODE_NODE) {
2516 CCode *cc = (CCode *)node;
2517 if(cc->cctype == HT_CCODE)
2518 print_ccode_block((CCode *)node);
2524 generate_outfiles(void)
2528 print_file_comments();
2534 print_header_prefixes();
2536 print_version_macros();
2540 for(li=nodes;li;li=g_list_next(li)) {
2541 Node *node = li->data;
2542 if(node->type == CCODE_NODE) {
2543 CCode *cc = (CCode *)node;
2544 if(cc->cctype != HT_CCODE &&
2545 cc->cctype != AT_CCODE)
2546 print_ccode_block((CCode *)node);
2547 } else if(node->type == CLASS_NODE) {
2548 print_class_block((Class *)node);
2550 g_assert_not_reached();
2553 print_header_postfixes();
2559 fprintf(stderr, "Gob version %s\n\n", VERSION);
2560 fprintf(stderr, "gob [options] file.gob\n\n");
2561 fprintf(stderr, "Options:\n"
2562 "\t--help,-h,-? Display this help\n"
2563 "\t--version Display version\n"
2564 "\t--exit-on-warn,-w Exit with an error on warnings\n"
2565 "\t--no-exit-on-warn Don't exit on warnings [default]\n"
2566 "\t--for-cpp Create C++ files\n"
2567 "\t--no-extern-c Never print extern \"C\" into the "
2569 "\t--no-gnu Never use GNU extentions\n"
2570 "\t--no-touch-headers Don't touch headers unless they "
2572 "\t--always-private-header Always create a private header "
2574 "\t even if it would be empty "
2576 "\t--ondemand-private-header Create private header only when "
2578 "\t--no-private-header Don't create a private header, "
2580 "\t structure and protected "
2581 "prototypes inside c file\n"
2582 "\t--always-private-struct Always create a private pointer "
2584 "\t the object structure\n"
2585 "\t--no-write,-n Don't write output files, just "
2587 "\t--no-lines Don't print '#line' to output\n"
2588 "\t--no-self-alias Don't create self type and macro "
2590 "\t--no-kill-underscores Don't remove the leading underscore "
2592 "\t short id names\n");
2596 parse_options(int argc, char *argv[])
2599 int got_file = FALSE;
2600 int no_opts = FALSE;
2604 for(i = 1 ; i < argc; i++) {
2606 argv[i][0] != '-') {
2609 fprintf(stderr, "Specify only one file!\n");
2615 } else if(strcmp(argv[i], "--help")==0) {
2618 } else if(strcmp(argv[i], "--version")==0) {
2619 fprintf(stderr, "Gob version %s\n", VERSION);
2621 } else if(strcmp(argv[i], "--exit-on-warn")==0) {
2622 exit_on_warn = TRUE;
2623 } else if(strcmp(argv[i], "--no-exit-on-warn")==0) {
2624 exit_on_warn = FALSE;
2625 } else if(strcmp(argv[i], "--for-cpp")==0) {
2627 } else if(strcmp(argv[i], "--no-touch-headers")==0) {
2628 no_touch_headers = TRUE;
2629 } else if(strcmp(argv[i], "--ondemand-private-header")==0) {
2630 private_header = PRIVATE_HEADER_ONDEMAND;
2631 } else if(strcmp(argv[i], "--always-private-header")==0) {
2632 private_header = PRIVATE_HEADER_ALWAYS;
2633 } else if(strcmp(argv[i], "--no-private-header")==0) {
2634 private_header = PRIVATE_HEADER_NEVER;
2635 } else if(strcmp(argv[i], "--no-gnu")==0) {
2637 } else if(strcmp(argv[i], "--no-extern-c")==0) {
2639 } else if(strcmp(argv[i], "--no-write")==0) {
2641 } else if(strcmp(argv[i], "--no-lines")==0) {
2643 } else if(strcmp(argv[i], "--no-self-alias")==0) {
2644 no_self_alias = TRUE;
2645 } else if(strcmp(argv[i], "--no-kill-underscores")==0) {
2646 no_kill_underscores = TRUE;
2647 } else if(strcmp(argv[i], "--always-private-struct")==0) {
2648 always_private_struct = TRUE;
2649 } else if(strcmp(argv[i], "--")==0) {
2650 /*further arguments are files*/
2652 } else if(strncmp(argv[i], "--", 2)==0) {
2653 /*unknown long option*/
2654 fprintf(stderr, "Unknown option '%s'!\n", argv[i]);
2658 /*by now we know we have a string starting with
2659 - which is a short option string*/
2661 for(p = argv[i] + 1; *p; p++) {
2675 "Unknown option '%c'!\n", *p);
2684 /* this is a somewhat ugly hack, but it appears to work */
2686 compare_and_move_header(void)
2688 char *hfnew = g_strconcat("#gob#", filebase, ".h#gob#", NULL);
2689 char *hf = g_strconcat(filebase, ".h", NULL);
2691 if(stat(hf, &s) == 0) {
2693 s = g_strdup_printf("cmp '%s' '%s' > /dev/null", hf, hfnew);
2694 if(system(s) == 0) {
2695 if(unlink(hfnew) != 0)
2696 error_printf(GOB_ERROR, 0,
2697 "Can't remove new header file");
2705 error_printf(GOB_ERROR, 0,
2706 "Can't remove old header file");
2708 if(rename(hfnew, hf) != 0)
2709 error_printf(GOB_ERROR, 0,
2710 "Can't rename new header file");
2716 main(int argc, char *argv[])
2718 parse_options(argc, argv);
2721 yyin = fopen(filename, "r");
2723 fprintf(stderr, "Error: can't open file '%s'\n",
2730 /* This is where parsing is done */
2733 g_error("Parsing errors, quitting");
2736 error_print(GOB_ERROR, 0, " no class defined");
2739 exit_on_error = FALSE;
2741 signals = count_signals((Class *)class);
2742 set_arguments = count_set_arguments((Class *)class);
2743 get_arguments = count_get_arguments((Class *)class);
2744 overrides = count_overrides((Class *)class);
2745 privates = count_privates((Class *)class);
2746 protecteds = count_protecteds((Class *)class);
2747 destructors = count_destructors((Class *)class);
2748 initializers = count_initializers((Class *)class);
2751 make_inits((Class *)class);
2752 if(destructors > 0) {
2753 need_destroy = TRUE;
2754 find_destroy((Class *)class);
2757 need_finalize = TRUE;
2758 find_finalize((Class *)class);
2760 check_bad_symbols((Class *)class);
2761 check_duplicate_symbols((Class *)class);
2762 check_duplicate_overrides((Class *)class);
2763 check_duplicate_signals_args((Class *)class);
2764 check_public_new((Class *)class);
2765 check_vararg((Class *)class);
2766 check_firstarg((Class *)class);
2767 check_nonvoidempty((Class *)class);
2768 check_signal_args((Class *)class);
2769 check_argument_types((Class *)class);
2770 check_func_arg_checks((Class *)class);
2772 exit_on_error = TRUE;
2777 any_special = setup_special_array((Class *)class, special_array);
2781 generate_outfiles();
2792 if(no_touch_headers &&
2794 compare_and_move_header();