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 cl->nodes = g_list_prepend(cl->nodes, node);
566 node = new_method(NO_SCOPE, INIT_METHOD,
567 (Type *)new_type(g_strdup("void"),
569 NULL, NULL, NULL, g_strdup("init"),
570 make_func_arg(cl->otype, FALSE, g_strdup("o")),
571 NULL, NULL, NULL, 0, 0, FALSE,
573 cl->nodes = g_list_prepend(cl->nodes, node);
578 find_destroy(Class *cl)
582 destroy_handler = NULL;
583 for(li=cl->nodes;li;li=g_list_next(li)) {
585 if(n->type == METHOD_NODE) {
586 Method *m = (Method *)n;
587 if(m->method == OVERRIDE_METHOD &&
588 strcmp(m->id, "destroy")==0) {
589 if(strcmp(m->otype, "Gtk:Object") != 0) {
590 error_print(GOB_ERROR, m->line_no,
591 "destroy method override "
592 "of class other then "
595 if(g_list_length(m->args) != 1) {
596 error_print(GOB_ERROR, m->line_no,
597 "destroy method override "
598 "with more then one "
609 find_finalize(Class *cl)
613 finalize_handler = NULL;
614 for(li=cl->nodes;li;li=g_list_next(li)) {
616 if(n->type == METHOD_NODE) {
617 Method *m = (Method *)n;
618 if(m->method == OVERRIDE_METHOD &&
619 strcmp(m->id, "finalize")==0) {
620 if(strcmp(m->otype, "Gtk:Object") != 0 &&
621 strcmp(m->otype, "G:Object") != 0) {
622 error_print(GOB_ERROR, m->line_no,
623 "finalize method override "
624 "of class other then "
625 "Gtk:Object (or G:Object"
628 if(g_list_length(m->args) != 1) {
629 error_print(GOB_ERROR, m->line_no,
630 "finalize method override "
631 "with more then one "
634 finalize_handler = m;
642 /* hash of method -> name of signal prototype */
643 static GHashTable *marsh = NULL;
645 /* list of methods with different signal prototypes,
646 we check this list if we can use a signal prototype of a
647 previous signal method, there are only uniques here */
648 static GList *eq_signal_methods = NULL;
650 /* compare a list of strings */
652 is_list_equal(GList *a, GList *b)
654 for(;a && b; a=a->next, b=b->next) {
655 if(strcmp(a->data, b->data)!=0) {
659 /* the the lists were different length */
666 find_same_type_signal(Method *m)
669 for(li=eq_signal_methods;li;li=li->next) {
670 Method *mm = li->data;
671 if(is_list_equal(mm->gtktypes, m->gtktypes))
678 print_signal_marsal_args(Method *m)
680 if(strcmp(m->gtktypes->next->data, "NONE")!=0) {
683 for(i=0, li=m->gtktypes->next;li;
684 i++, li=g_list_next(li)) {
686 out_printf(out, ",\n\t\tGTK_VALUE_%s(args[%d])",
687 (char *)li->data, i);
689 out_printf(out, ",\n\t\t(%s)"
690 "GTK_VALUE_%s(args[%d])",
691 get_cast(li->data, FALSE),
692 (char *)li->data, i);
696 out_printf(out, ",\n\t\tfunc_data);\n}\n\n");
701 add_signal_prots(Method *m)
708 if(m->method != SIGNAL_LAST_METHOD &&
709 m->method != SIGNAL_FIRST_METHOD)
713 marsh = g_hash_table_new(NULL, NULL);
715 if(strcmp(m->gtktypes->data, "NONE")==0 &&
716 strcmp(m->gtktypes->next->data, "NONE")==0)
719 /* if we already did a signal prototype just use that */
720 mm = find_same_type_signal(m);
722 s = g_hash_table_lookup(marsh, mm);
723 g_hash_table_insert(marsh, m, s);
727 s = g_strdup_printf("Sig%d", sig++);
729 g_hash_table_insert(marsh, m, s);
730 eq_signal_methods = g_list_prepend(eq_signal_methods, m);
732 /* we know that we'll know all the gtktypes (so get_cast can't fail) */
733 out_printf(out, "\ntypedef %s (*___%s) (%s *, ",
734 get_cast(m->gtktypes->data, FALSE), s, typebase);
736 if(strcmp(m->gtktypes->next->data, "NONE")!=0) {
737 for(li=m->gtktypes->next; li; li=g_list_next(li))
738 out_printf(out, "%s, ", get_cast(li->data, FALSE));
740 out_printf(out, "gpointer);\n");
742 out_printf(out, "\nstatic void\n"
743 "___marshal_%s (GtkObject * object,\n"
744 "\tGtkSignalFunc func,\n"
745 "\tgpointer func_data,\n"
749 if(strcmp(m->gtktypes->data, "NONE")==0) {
750 out_printf(out, "\t___%s rfunc;\n\n"
751 "\trfunc = (___%s)func;\n\n"
752 "\t(*rfunc)((%s *)object", s, s, typebase);
754 const char *retcast = get_cast(m->gtktypes->data, FALSE);
758 "\trfunc = (___%s)func;\n\n"
759 "\tretval = GTK_RETLOC_%s(args[%d]);\n\n"
760 "\t*retval = (*rfunc)((%s *)object",
761 s, retcast, s, (char *)m->gtktypes->data,
762 g_list_length(m->gtktypes)-1, typebase);
764 print_signal_marsal_args(m);
772 out_printf(out, "\n");
774 out_printf(out, "enum {\n");
775 for(li=c->nodes;li;li=g_list_next(li)) {
777 if(n->type == METHOD_NODE) {
778 Method *m = (Method *)n;
779 if(m->method == SIGNAL_LAST_METHOD ||
780 m->method == SIGNAL_FIRST_METHOD) {
781 char *s = g_strdup(get_real_id(m->id));
783 out_printf(out, "\t%s_SIGNAL,\n", s);
788 out_printf(out, "\tLAST_SIGNAL\n};\n\n");
790 if(set_arguments > 0 || get_arguments > 0) {
791 out_printf(out, "enum {\n\tARG_0");
792 for(li=c->nodes;li;li=g_list_next(li)) {
794 if(n->type == ARGUMENT_NODE) {
795 Argument *a = (Argument *)n;
796 char *s = g_strdup(a->name);
798 out_printf(out, ",\n\tARG_%s", s);
802 out_printf(out, "\n};\n\n");
807 "static guint object_signals[LAST_SIGNAL] = {0};\n\n");
809 out_printf(out, "/* pointer to the class of our parent */\n");
810 out_printf(out, "static %sClass *parent_class = NULL;\n\n", ptypebase);
816 char *chunk_size = ((Class*)class)->chunk_size;
820 "%s_get_type (void)\n"
822 "\tstatic GtkType type = 0;\n\n"
823 "\tif (type == 0) {\n"
824 "\t\tstatic const GtkTypeInfo info = {\n"
826 "\t\t\tsizeof (%s),\n"
827 "\t\t\tsizeof (%sClass),\n"
828 "\t\t\t(GtkClassInitFunc) %s_class_init,\n"
829 "\t\t\t(GtkObjectInitFunc) %s_init,\n"
830 "\t\t\t/* reserved_1 */ NULL,\n"
831 "\t\t\t/* reserved_2 */ NULL,\n"
832 "\t\t\t(GtkClassInitFunc) NULL\n"
834 "\t\ttype = gtk_type_unique (%s_get_type(), &info);\n",
835 funcbase, typebase, typebase, typebase,
836 funcbase, funcbase, pfuncbase);
840 "\t\tgtk_type_set_chunk_alloc(type, %s);\n"
842 chunk_size, chunk_size);
851 add_overrides(Class *c, const char *oname, gboolean did_base_obj)
857 done = g_hash_table_new(g_str_hash, g_str_equal);
859 s = g_strdup("GtkObject"); /* This was already done */
860 g_hash_table_insert(done, s, s);
861 s = g_strdup("GObject"); /* This was probably already done as well (if using Gtk/Glib 1.3/2.0) */
862 g_hash_table_insert(done, s, s);
864 for(li=c->nodes; li; li=g_list_next(li)) {
867 Method *m = (Method *)n;
868 if(n->type != METHOD_NODE ||
869 m->method != OVERRIDE_METHOD)
872 s = remove_sep(m->otype);
874 if(g_hash_table_lookup(done, s)) {
878 g_hash_table_insert(done, s, s);
880 f = replace_sep(m->otype, '_');
883 out_printf(out, "\t%sClass *%s_class = (%sClass *)%s;\n",
888 g_hash_table_foreach(done, (GHFunc)g_free, NULL);
889 g_hash_table_destroy(done);
893 make_run_signal_flags(Method *m, gboolean last)
907 gs = g_string_new(NULL);
910 g_string_assign(gs, "GTK_RUN_LAST");
912 g_string_assign(gs, "GTK_RUN_FIRST");
914 if(m->scope == PUBLIC_SCOPE)
915 g_string_append(gs, " | GTK_RUN_ACTION");
917 for(li = m->flags; li; li = li->next) {
918 char *flag = li->data;
920 for(i=0;flags[i];i++) {
921 if(strcmp(flags[i], flag)==0)
924 /* if we haven't found it in our list */
926 error_printf(GOB_WARN, m->line_no,
927 "Unknown flag '%s' used, "
928 "perhaps it was misspelled",
931 g_string_sprintfa(gs, " | GTK_RUN_%s", flag);
936 g_string_free(gs, FALSE);
943 add_signals(Class *c)
947 out_printf(out, "\n");
948 for(li=c->nodes;li;li=g_list_next(li)) {
950 char *mar, *sig, *flags;
951 gboolean is_none, last = FALSE;
952 Method *m = (Method *)n;
954 if(n->type != METHOD_NODE ||
955 (m->method != SIGNAL_FIRST_METHOD &&
956 m->method != SIGNAL_LAST_METHOD))
959 if(m->method == SIGNAL_FIRST_METHOD)
964 if(g_hash_table_lookup(marsh, m))
965 mar = g_strconcat("___marshal_",
966 (char *)g_hash_table_lookup(marsh, m),
969 mar = g_strdup("gtk_signal_default_marshaller");
971 is_none = (strcmp(m->gtktypes->next->data, "NONE")==0);
973 sig = g_strdup(get_real_id(m->id));
975 flags = make_run_signal_flags(m, last);
976 out_printf(out, "\tobject_signals[%s_SIGNAL] =\n"
977 "\t\tgtk_signal_new (\"%s\",\n"
978 "\t\t\t(GtkSignalRunType)(%s),\n"
979 "\t\t\tGTK_CLASS_TYPE(gtk_object_class),\n"
980 "\t\t\tGTK_SIGNAL_OFFSET (%sClass, %s),\n"
982 "\t\t\tGTK_TYPE_%s, %d",
983 sig, get_real_id(m->id),
985 typebase, get_real_id(m->id), mar,
986 (char *)m->gtktypes->data,
987 is_none ? 0 : g_list_length(m->gtktypes->next));
994 for(l = m->gtktypes->next; l != NULL; l = l->next)
995 out_printf(out, ",\n\t\t\tGTK_TYPE_%s",
999 out_printf(out, ");\n");
1001 if(strcmp(m->gtktypes->data, "NONE") != 0 ||
1005 out_printf(out, "\tif(");
1006 if(strcmp(m->gtktypes->data, "NONE") != 0) {
1007 out_printf(out, "%s sizeof(", sep);
1008 print_type(out, m->mtype, FALSE);
1009 out_printf(out, "%s",
1011 m->mtype->postfix : "");
1012 out_printf(out, ") != sizeof(%s)",
1013 get_cast(m->gtktypes->data, FALSE));
1018 for(al = m->args->next, gl = m->gtktypes->next;
1019 al != NULL && gl != NULL;
1020 al = al->next, gl = gl->next) {
1021 FuncArg *arg = al->data;
1022 char *gtkarg = gl->data;
1024 out_printf(out, "%ssizeof(", sep);
1025 print_type(out, arg->atype, FALSE);
1026 out_printf(out, "%s",
1027 arg->atype->postfix ?
1028 arg->atype->postfix : "");
1029 out_printf(out, ") != sizeof(%s)",
1030 get_cast(gtkarg, FALSE));
1034 out_printf(out, ") {\n"
1035 "\t\tg_error(\"%s line %d: Type mismatch "
1036 "of \\\"%s\\\" signal signature\");\n"
1038 filename, m->line_no, get_real_id(m->id));
1042 out_printf(out, "\tgtk_object_class_add_signals (gtk_object_class,\n"
1043 "\t\tobject_signals, LAST_SIGNAL);\n\n");
1047 set_def_handlers(Class *c, const char *oname)
1050 gboolean set_line = FALSE;
1052 out_printf(out, "\n");
1053 for(li = c->nodes; li; li = g_list_next(li)) {
1055 Method *m = (Method *)n;
1057 if(n->type != METHOD_NODE ||
1058 (m->method != SIGNAL_FIRST_METHOD &&
1059 m->method != SIGNAL_LAST_METHOD &&
1060 m->method != VIRTUAL_METHOD &&
1061 m->method != OVERRIDE_METHOD))
1064 if(m->line_no > 0 && m->cbuf) {
1065 out_addline_infile(out, m->line_no);
1067 } else if(set_line) {
1068 out_addline_outfile(out);
1073 if(m->method == OVERRIDE_METHOD) {
1075 s = replace_sep(m->otype, '_');
1080 strcmp(get_real_id(m->id), "destroy") == 0)
1081 out_printf(out, "\tgtk_object_class->destroy "
1083 else if(need_finalize &&
1085 strcmp(get_real_id(m->id), "finalize") == 0)
1087 "#ifdef G_OBJECT_CLASS\n"
1088 "\tg_object_class->finalize = ___finalize;\n"
1089 "#else /* !G_OBJECT_CLASS */\n"
1090 "\tgtk_object_class->finalize = ___finalize;\n"
1091 "#endif /* G_OBJECT_CLASS */\n");
1094 "\t%s_class->%s = ___%x_%s_%s;\n",
1095 s, get_real_id(m->id), (guint)m->unique_id,
1096 funcbase, get_real_id(m->id));
1098 out_printf(out, "\t%s_class->%s = NULL;\n",
1099 s, get_real_id(m->id));
1102 out_printf(out, "\t%s->%s = ___real_%s_%s;\n",
1103 oname, get_real_id(m->id),
1104 funcbase, get_real_id(m->id));
1106 out_printf(out, "\t%s->%s = NULL;\n",
1107 oname, get_real_id(m->id));
1111 out_addline_outfile(out);
1115 make_arguments(Class *c)
1118 char *argflags[] = {
1126 out_printf(out, "\n");
1127 for(li=c->nodes;li;li=g_list_next(li)) {
1133 if(n->type != ARGUMENT_NODE)
1138 if(a->get && a->set)
1139 flags = g_string_new("GTK_ARG_READWRITE");
1141 flags = g_string_new("GTK_ARG_READABLE");
1143 flags = g_string_new("GTK_ARG_WRITABLE");
1145 g_assert(a->get || a->set);
1147 for(l=a->flags;l;l=g_list_next(l)) {
1148 char *flag = l->data;
1150 if(strcmp(flag, "READWRITE")==0 ||
1151 strcmp(flag, "READABLE")==0 ||
1152 strcmp(flag, "WRITABLE")==0) {
1153 error_print(GOB_WARN, a->line_no,
1154 "READWRITE, READABLE and "
1155 "WRITABLE argument flags are "
1156 "set automatically");
1159 for(i = 0; argflags[i]; i++) {
1160 if(strcmp(argflags[i], flag)==0)
1163 /* if we haven't found it in our list */
1164 if( ! argflags[i]) {
1165 error_printf(GOB_WARN, a->line_no,
1166 "Unknown flag '%s' used, "
1167 "perhaps it was misspelled", flag);
1169 g_string_sprintfa(flags, " | GTK_ARG_%s", flag);
1172 s = g_strdup(a->name);
1174 out_printf(out, "\tgtk_object_add_arg_type(\"%s::%s\",\n"
1175 "\t\tGTK_TYPE_%s,\n"
1178 typebase, a->name, a->gtktype, flags->str, s);
1180 g_string_free(flags, TRUE);
1183 out_printf(out, "\n");
1184 if(get_arguments > 0)
1185 out_printf(out, "\tgtk_object_class->get_arg = ___object_get_arg;\n");
1186 if(set_arguments > 0)
1187 out_printf(out, "\tgtk_object_class->set_arg = ___object_set_arg;\n");
1191 print_initializer(Method *m, Variable *v)
1195 if(v->initializer == NULL)
1198 if(v->scope == PRIVATE_SCOPE)
1199 root = g_strconcat(((FuncArg *)m->args->data)->name,
1202 root = g_strdup(((FuncArg *)m->args->data)->name);
1204 if(v->initializer_line > 0)
1205 out_addline_infile(out, v->initializer_line);
1207 out_printf(out, "\t%s->%s = %s;\n",
1208 root, v->id, v->initializer);
1210 if(v->initializer_line > 0)
1211 out_addline_outfile(out);
1217 print_destructor(Variable *v)
1221 if(v->destructor == NULL)
1224 if(v->scope == PRIVATE_SCOPE)
1225 root = "self->_priv";
1229 if(v->destructor_simple) {
1230 if(v->destructor_line > 0)
1231 out_addline_infile(out, v->destructor_line);
1233 out_printf(out, "\tif(%s->%s) { "
1234 "((*(void (*)(void *))%s)) (%s->%s); "
1235 "%s->%s = NULL; }\n",
1236 root, v->id, v->destructor, root, v->id,
1239 if(v->destructor_line > 0)
1240 out_addline_outfile(out);
1242 out_printf(out, "#define VAR (%s->%s)\n", root, v->id);
1243 out_printf(out, "\t{\n");
1244 if(v->destructor_line > 0)
1245 out_addline_infile(out, v->destructor_line);
1247 out_printf(out, "\t%s}\n", v->destructor);
1249 if(v->destructor_line > 0)
1250 out_addline_outfile(out);
1251 out_printf(out, "\tmemset(&VAR, 0, sizeof(VAR));\n");
1252 out_printf(out, "#undef VAR\n");
1257 add_destroy(Class *c)
1259 out_printf(out, "\nstatic void\n"
1260 "___destroy(GtkObject *obj_self)\n"
1263 "#define __GOB_FUNCTION__ \"%s::destroy\"\n",
1266 if(destructors > 0) {
1267 out_printf(out, "\t%s *self = %s (obj_self);\n",
1268 typebase, macrobase);
1271 if(destroy_handler) {
1272 /* so we get possible bad argument warning */
1273 if(destroy_handler->line_no > 0)
1274 out_addline_infile(out, destroy_handler->line_no);
1275 out_printf(out, "\t___%x_%s_destroy(obj_self);\n",
1276 (guint)destroy_handler->unique_id, funcbase);
1277 if(destroy_handler->line_no > 0)
1278 out_addline_outfile(out);
1281 "\tif(GTK_OBJECT_CLASS(parent_class)->destroy) \\\n"
1282 "\t\t(* GTK_OBJECT_CLASS(parent_class)->destroy)(obj_self);\n");
1285 if(destructors > 0) {
1287 for(li = ((Class *)class)->nodes;
1291 Variable *v = (Variable *)n;
1292 if(n->type == VARIABLE_NODE &&
1293 v->scope != CLASS_SCOPE)
1294 print_destructor(v);
1298 out_printf(out, "\treturn;\n");
1300 out_printf(out, "\tself = NULL;\n");
1301 out_printf(out, "}\n"
1302 "#undef __GOB_FUNCTION__\n\n");
1306 add_finalize(Class *c)
1308 /* Sort of a hack to make it work with gtk+ 1.3/2.0 */
1310 "\n#ifdef G_OBJECT_CLASS\n"
1312 "___finalize(GObject *obj_self)\n"
1313 "#else /* !G_OBJECT_CLASS */\n"
1315 "___finalize(GtkObject *obj_self)\n"
1316 "#endif /* G_OBJECT_CLASS */\n"
1319 "#define __GOB_FUNCTION__ \"%s::finalize\"\n",
1323 out_printf(out, "\t%s *self = %s (obj_self);\n",
1324 typebase, macrobase);
1325 out_printf(out, "\tgpointer priv = self->_priv;\n");
1328 if(finalize_handler) {
1329 /* so we get possible bad argument warning */
1330 if(finalize_handler->line_no > 0)
1331 out_addline_infile(out, finalize_handler->line_no);
1332 out_printf(out, "\t___%x_%s_finalize(obj_self);\n",
1333 (guint)finalize_handler->unique_id, funcbase);
1334 if(finalize_handler->line_no > 0)
1335 out_addline_outfile(out);
1337 /* Sort of a hack to make it work with gtk+ 1.3/2.0 */
1339 "#ifdef G_OBJECT_CLASS\n"
1340 "\tif(G_OBJECT_CLASS(parent_class)->finalize) \\\n"
1341 "\t\t(* G_OBJECT_CLASS(parent_class)->finalize)(obj_self);\n"
1342 "#else /* !G_OBJECT_CLASS */\n"
1343 "\tif(GTK_OBJECT_CLASS(parent_class)->finalize) \\\n"
1344 "\t\t(* GTK_OBJECT_CLASS(parent_class)->finalize)(obj_self);\n"
1345 "#endif /* G_OBJECT_CLASS */\n");
1349 out_printf(out, "\tg_free(priv);\n");
1352 out_printf(out, "}\n"
1353 "#undef __GOB_FUNCTION__\n\n");
1360 for(li=c->nodes;li;li=g_list_next(li)) {
1364 gboolean add_unused_class = FALSE;
1366 if(n->type != METHOD_NODE)
1369 if(m->method == INIT_METHOD) {
1371 out_addline_infile(out, m->line_no);
1372 print_method(out, "static ", "\n", "", " ", "", "\n",
1373 m, FALSE, FALSE, TRUE);
1375 out_addline_outfile(out);
1376 out_printf(out, "{\n"
1377 "#define __GOB_FUNCTION__ \"%s::init\"\n",
1380 out_printf(out, "\t%s->_priv = "
1381 "g_new0 (%sPrivate, 1);\n",
1382 ((FuncArg *)m->args->data)->name,
1384 } else if(always_private_struct) {
1385 out_printf(out, "\t%s->_priv = NULL;\n",
1386 ((FuncArg *)m->args->data)->name);
1388 if(initializers > 0) {
1390 for(li = ((Class *)class)->nodes;
1394 Variable *v = (Variable *)n;
1395 if(n->type != VARIABLE_NODE ||
1396 v->scope == CLASS_SCOPE)
1398 print_initializer(m, v);
1401 } else if(m->method == CLASS_INIT_METHOD) {
1402 gboolean did_base_obj = FALSE;
1405 out_addline_infile(out, m->line_no);
1406 print_method(out, "static ", "\n", "", " ", "", "\n",
1407 m, FALSE, FALSE, TRUE);
1409 out_addline_outfile(out);
1410 out_printf(out, "{\n"
1411 "#define __GOB_FUNCTION__ \"%s::class_init\"\n",
1414 set_arguments > 0 ||
1415 get_arguments > 0 ||
1418 add_unused_class = TRUE;
1420 "\tGtkObjectClass *"
1421 "gtk_object_class = "
1422 "(GtkObjectClass*) %s;\n",
1423 ((FuncArg *)m->args->data)->name);
1425 "#ifdef G_OBJECT_CLASS\n"
1428 "(GObjectClass*) %s;\n"
1429 "#endif /* G_OBJECT_CLASS */\n",
1430 ((FuncArg *)m->args->data)->name);
1431 did_base_obj = TRUE;
1436 ((FuncArg *)m->args->data)->name,
1439 if(initializers > 0) {
1441 for(li = ((Class *)class)->nodes;
1445 Variable *v = (Variable *)n;
1446 if(n->type == VARIABLE_NODE &&
1447 v->scope == CLASS_SCOPE)
1448 print_initializer(m, v);
1452 out_printf(out, "\n\tparent_class = ");
1454 out_printf(out, "(%sClass *)", ptypebase);
1455 out_printf(out, "gtk_type_class (%s_get_type ());\n",
1461 set_def_handlers(c, ((FuncArg *)m->args->data)->name);
1463 /* if there are no handlers for these things, we
1464 * need to set them up here */
1465 if(need_destroy && !destroy_handler)
1466 out_printf(out, "\tgtk_object_class->destroy "
1468 if(need_finalize && !finalize_handler)
1470 "#ifdef G_OBJECT_CLASS\n"
1471 "\tg_object_class->finalize = ___finalize;\n"
1472 "#else /* !G_OBJECT_CLASS */\n"
1473 "\tgtk_object_class->finalize = ___finalize;\n"
1474 "#endif /* G_OBJECT_CLASS */\n");
1476 if(get_arguments > 0 || set_arguments > 0)
1483 out_printf(out, " {\n");
1484 out_addline_infile(out, m->ccode_line);
1485 out_printf(out, "%s\n", m->cbuf);
1486 out_addline_outfile(out);
1487 out_printf(out, " }\n");
1489 out_printf(out, "\treturn;\n");
1492 ((FuncArg *)m->args->data)->name);
1493 if(add_unused_class) {
1495 "\tgtk_object_class = NULL;\n"
1496 "#ifdef G_OBJECT_CLASS\n"
1497 "\tg_object_class = NULL;\n"
1498 "#endif /* G_OBJECT_CLASS */\n");
1500 out_printf(out, "}\n"
1501 "#undef __GOB_FUNCTION__\n");
1506 add_getset_arg(Class *c, gboolean is_set)
1509 out_printf(out, "\nstatic void\n"
1510 "___object_%s_arg (GtkObject *object,\n"
1513 "#define __GOB_FUNCTION__ \"%s::%s_arg\"\n"
1516 "\tself = %s (object);\n\n"
1517 "\tswitch (arg_id) {\n",
1518 is_set ? "set" : "get",
1519 c->otype, is_set ? "set" : "get",
1520 typebase, macrobase);
1522 for(li=c->nodes;li;li=g_list_next(li)) {
1528 if(n->type != ARGUMENT_NODE)
1533 line_no = a->set_line;
1536 line_no = a->get_line;
1540 s = g_strdup(a->name);
1542 out_printf(out, "\tcase ARG_%s:\n", s);
1543 if(is_set && a->atype) {
1544 char *cast = get_type(a->atype, TRUE);
1545 if(no_gnu || for_cpp) {
1546 out_printf(out, "#define ARG "
1547 "((%s)GTK_VALUE_%s(*arg))\n",
1550 out_printf(out, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
1551 if(strcmp(a->gtktype, "OBJECT")==0) {
1552 out_printf(out, "#define ARG "
1554 "GTK_VALUE_POINTER(*arg); "
1558 out_printf(out, "#define ARG "
1560 "GTK_VALUE_%s(*arg); "
1564 out_printf(out, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
1565 out_printf(out, "#define ARG "
1566 "((%s)GTK_VALUE_%s(*arg))\n",
1568 out_printf(out, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n");
1570 out_printf(out, "\t\t{\n");
1572 } else if(!is_set && strcmp(a->gtktype, "OBJECT")==0) {
1574 "#define ARG (GTK_VALUE_POINTER(*arg))\n"
1578 "#define ARG (GTK_VALUE_%s(*arg))\n"
1584 out_addline_infile(out, line_no);
1585 out_printf(out, "%s\n", cbuf);
1587 out_addline_outfile(out);
1588 out_printf(out, "\t\t}\n\t\tbreak;\n"
1591 out_printf(out, "\tdefault:\n\t\tbreak;\n\t}\n"
1592 "\treturn;\n\tself = NULL;\n\targ = NULL;\n}\n"
1593 "#undef __GOB_FUNCTION__\n");
1597 print_checks(Method *m, FuncArg *fa)
1601 gboolean checked_null = FALSE;
1602 is_void = (strcmp(m->mtype->name, "void")==0 &&
1603 m->mtype->pointer == NULL);
1605 for(li = fa->checks; li; li = g_list_next(li)) {
1606 Check *ch = li->data;
1608 /* point to the method prot in .gob for failed checks */
1610 out_addline_infile(out, m->line_no);
1612 out_printf(out, "\tg_return_if_fail (");
1614 out_printf(out, "\tg_return_val_if_fail (");
1615 switch(ch->chtype) {
1617 out_printf(out, "%s != NULL", fa->name);
1618 checked_null = TRUE;
1621 s = make_pre_macro(fa->atype->name, "IS");
1623 out_printf(out, "%s (%s)", s, fa->name);
1625 /* if not check null, null may be valid */
1626 out_printf(out, "!(%s) || %s (%s)", fa->name,
1631 out_printf(out, "%s < %s", fa->name, ch->number);
1634 out_printf(out, "%s > %s", fa->name, ch->number);
1637 out_printf(out, "%s <= %s", fa->name, ch->number);
1640 out_printf(out, "%s >= %s", fa->name, ch->number);
1643 out_printf(out, "%s == %s", fa->name, ch->number);
1646 out_printf(out, "%s != %s", fa->name, ch->number);
1650 out_printf(out, ");\n");
1652 out_printf(out, ", (");
1653 print_type(out, m->mtype, TRUE);
1654 out_printf(out, ")%s);\n",
1655 m->onerror?m->onerror:"0");
1661 print_preconditions(Method *m)
1665 for(li=m->args;li;li=g_list_next(li)) {
1666 FuncArg *fa = li->data;
1668 print_checks(m, fa);
1671 out_addline_outfile(out);
1675 print_method_body(Method *m, int pre)
1677 out_printf(out, "{\n"
1678 "#define __GOB_FUNCTION__ \"%s::%s\"\n",
1679 ((Class *)class)->otype,
1680 get_real_id(m->id));
1682 print_preconditions(m);
1684 /* Note: the trailing }'s are on one line, this is so
1685 that we get the no return warning correctly and point to
1686 the correct line in the .gob file, yes this is slightly
1687 ugly in the .c file, but that is not supposed to be
1688 human readable anyway. */
1690 out_printf(out, "{\n");
1692 out_addline_infile(out, m->ccode_line);
1693 out_printf(out, "\t%s}", m->cbuf);
1696 /* Note, there is no \n between the last } and this } so that
1697 * errors/warnings reported on the end of the body get pointed to the
1698 * right line in the .gob source */
1699 out_printf(out, "}\n");
1702 out_addline_outfile(out);
1703 out_printf(out, "#undef __GOB_FUNCTION__\n");
1707 put_signal_args(Method *m)
1711 for(ali = m->gtktypes->next, li=m->args->next;
1713 li=li->next, ali=ali->next) {
1714 FuncArg *fa = li->data;
1715 const char *cast = get_cast(ali->data, FALSE);
1716 /* we should have already proved before that
1717 the we know all the types */
1720 out_printf(out, ",\n\t\t(%s)%s", cast,
1726 get_arg_names_for_macro(Method *m)
1730 GString *gs = g_string_new(NULL);
1732 for(li=m->args;li;li=g_list_next(li)) {
1733 FuncArg *arg = li->data;
1734 g_string_sprintfa(gs, "%s___%s", p, arg->name);
1738 g_string_free(gs, FALSE);
1743 put_method(Method *m)
1745 char *s, *args, *doc;
1747 is_void = (strcmp(m->mtype->name, "void")==0 &&
1748 m->mtype->pointer == NULL);
1749 out_printf(out, "\n");
1750 if(m->method != OVERRIDE_METHOD) {
1751 doc = get_gtk_doc(m->id);
1753 out_printf(out, "%s", doc);
1758 case REGULAR_METHOD:
1760 out_addline_infile(out, m->line_no);
1761 if(m->scope == PRIVATE_SCOPE)
1762 print_method(out, "static ", "\n", "", " ", "", "\n",
1763 m, FALSE, FALSE, TRUE);
1764 else /* PUBLIC, PROTECTED */
1765 print_method(out, "", "\n", "", " ", "", "\n",
1766 m, FALSE, FALSE, TRUE);
1767 print_method_body(m, TRUE);
1768 /* the outfile line was added above */
1770 case SIGNAL_FIRST_METHOD:
1771 case SIGNAL_LAST_METHOD:
1773 out_addline_infile(out, m->line_no);
1774 if(m->scope == PRIVATE_SCOPE)
1775 print_method(out, "static ", "\n", "", " ", "", "\n",
1776 m, FALSE, FALSE, TRUE);
1777 else /* PUBLIC, PROTECTED */
1778 print_method(out, "", "\n", "", " ", "", "\n",
1779 m, FALSE, FALSE, TRUE);
1780 out_addline_outfile(out);
1781 out_printf(out, "{\n");
1782 s = g_strdup(get_real_id(m->id));
1784 if(strcmp(m->mtype->name, "void") == 0 &&
1785 m->mtype->pointer == NULL) {
1786 print_preconditions(m);
1787 if(((FuncArg *)m->args->data)->name)
1788 out_printf(out, "\tgtk_signal_emit (GTK_OBJECT (%s),\n"
1789 "\t\tobject_signals[%s_SIGNAL]",
1790 ((FuncArg *)m->args->data)->name, s);
1792 out_printf(out, ");\n}\n");
1794 out_printf(out, "\t");
1795 print_type(out, m->mtype, TRUE);
1796 out_printf(out, "return_val = (");
1797 print_type(out, m->mtype, TRUE);
1799 out_printf(out, ")(%s);\n", m->defreturn);
1801 out_printf(out, ")(%s);\n", m->onerror);
1803 out_printf(out, ")(0);\n");
1804 print_preconditions(m);
1805 out_printf(out, "\tgtk_signal_emit (GTK_OBJECT (%s),\n"
1806 "\t\tobject_signals[%s_SIGNAL]",
1807 ((FuncArg *)m->args->data)->name, s);
1809 out_printf(out, ",\n\t\t&return_val);\n"
1810 "\treturn return_val;\n}\n");
1816 out_addline_infile(out, m->line_no);
1817 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
1818 m, FALSE, FALSE, TRUE);
1819 print_method_body(m, FALSE);
1820 /* the outfile line was added above */
1822 case VIRTUAL_METHOD:
1824 out_addline_infile(out, m->line_no);
1825 if(m->scope==PRIVATE_SCOPE)
1826 print_method(out, "static ", "\n", "", " ", "", "\n",
1827 m, FALSE, FALSE, TRUE);
1828 else /* PUBLIC, PROTECTED */
1829 print_method(out, "", "\n", "", " ", "", "\n",
1830 m, FALSE, FALSE, TRUE);
1831 out_addline_outfile(out);
1832 out_printf(out, "{\n"
1833 "\t%sClass *klass;\n", typebase);
1834 print_preconditions(m);
1835 out_printf(out, "\tklass = %s_GET_CLASS(%s);\n\n"
1836 "\tif(klass->%s)\n",
1837 macrobase, ((FuncArg *)m->args->data)->name,
1838 get_real_id(m->id));
1839 if(strcmp(m->mtype->name, "void") == 0 &&
1840 m->mtype->pointer == NULL) {
1842 out_printf(out, "\t\t(*klass->%s)(%s",
1844 ((FuncArg *)m->args->data)->name);
1845 for(li=m->args->next;li;li=g_list_next(li)) {
1846 FuncArg *fa = li->data;
1847 out_printf(out, ",%s", fa->name);
1849 out_printf(out, ");\n}\n");
1852 out_printf(out, "\t\treturn (*klass->%s)(%s",
1854 ((FuncArg *)m->args->data)->name);
1855 for(li=m->args->next;li;li=g_list_next(li)) {
1856 FuncArg *fa = li->data;
1857 out_printf(out, ",%s", fa->name);
1859 out_printf(out, ");\n"
1862 print_type(out, m->mtype, TRUE);
1864 out_printf(out, ")(%s);\n}\n", m->defreturn);
1866 out_printf(out, ")(%s);\n}\n", m->onerror);
1868 out_printf(out, ")(0);\n}\n");
1874 out_addline_infile(out, m->line_no);
1875 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
1876 m, FALSE, FALSE, TRUE);
1877 print_method_body(m, FALSE);
1878 /* the outfile line was added above */
1880 case OVERRIDE_METHOD:
1884 out_addline_infile(out, m->line_no);
1885 s = g_strdup_printf("\n___%x_", (guint)m->unique_id);
1886 print_method(out, "static ", s, "", " ", "", "\n",
1887 m, FALSE, FALSE, FALSE);
1889 out_addline_outfile(out);
1890 s = replace_sep(m->otype, '_');
1892 args = get_arg_names_for_macro(m);
1894 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
1895 "\t{ if(%s_CLASS(parent_class)->%s) \\\n"
1896 "\t\t(* %s_CLASS(parent_class)->%s)(%s); }\n",
1897 args, s, get_real_id(m->id), s, get_real_id(m->id), args);
1899 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
1900 "\t((%s_CLASS(parent_class)->%s)? \\\n"
1901 "\t\t(* %s_CLASS(parent_class)->%s)(%s): \\\n"
1903 args, s, get_real_id(m->id), s, get_real_id(m->id), args);
1904 out_printf(out, "(");
1905 print_type(out, m->mtype, TRUE);
1906 out_printf(out, ")%s))\n",
1907 m->onerror?m->onerror:"0");
1911 print_method_body(m, TRUE);
1912 /* the outfile line was added above */
1913 out_printf(out, "#undef PARENT_HANDLER\n");
1923 char *outfile, *outfileh, *outfileph;
1926 outfile = g_strconcat(filebase, ".c", NULL);
1928 outfile = g_strconcat(filebase, ".cc", NULL);
1929 if(no_touch_headers)
1930 outfileh = g_strconcat("#gob#", filebase, ".h#gob#", NULL);
1932 outfileh = g_strconcat(filebase, ".h", NULL);
1934 if((privates > 0 || protecteds > 0 ||
1935 private_header == PRIVATE_HEADER_ALWAYS) &&
1936 private_header != PRIVATE_HEADER_NEVER)
1937 outfileph = g_strconcat(filebase, "-private.h", NULL);
1943 devnull = fopen("/dev/null", "w");
1945 g_error("Cannot open null device");
1951 out = fopen(outfile, "w");
1953 g_error("Cannot open outfile: %s", outfile);
1955 outh = fopen(outfileh, "w");
1957 g_error("Cannot open outfile: %s", outfileh);
1959 outph = fopen(outfileph, "w");
1961 g_error("Cannot open outfile: %s", outfileh);
1967 put_argument_nongnu_wrappers(Class *c)
1971 if(get_arguments < 0 && set_arguments < 0)
1974 for(li=c->nodes;li;li=g_list_next(li)) {
1976 Argument *a = (Argument *)n;
1980 if(n->type != ARGUMENT_NODE)
1983 aname = g_strdup(a->name);
1987 cast = get_type(a->atype, TRUE);
1989 cast = g_strdup(get_cast(a->gtktype, TRUE));
1993 out_printf(outh, "#define %s_ARG_%s(arg) \t"
1994 "\"%s\",(%s)(arg)\n",
1995 macrobase, aname, a->name, cast);
1997 out_printf(outh, "#define %s_GET_ARG_%s(arg)\t"
1998 "\"%s\",(%s*)(arg)\n",
1999 macrobase, aname, a->name, cast);
2002 out_printf(outh, "#define %s_ARG_%s(arg) \t"
2004 macrobase, aname, a->name);
2006 out_printf(outh, "#define %s_GET_ARG_%s(arg)\t"
2008 macrobase, aname, a->name);
2016 put_argument_gnu_wrappers(Class *c)
2020 if(get_arguments < 0 && set_arguments < 0)
2023 for(li=c->nodes;li;li=g_list_next(li)) {
2025 Argument *a = (Argument *)n;
2028 if(n->type != ARGUMENT_NODE)
2030 s = g_strdup(a->name);
2033 cast = get_type(a->atype, TRUE);
2035 cast = g_strdup(get_cast(a->gtktype, TRUE));
2038 out_printf(outh, "#define %s_ARG_%s(arg) \t"
2039 "\"%s\",({%sz = (arg); z;})\n",
2040 macrobase, s, a->name, cast);
2042 out_printf(outh, "#define %s_GET_ARG_%s(arg)\t"
2043 "\"%s\",({%s*z = (arg); z;})\n",
2044 macrobase, s, a->name, cast);
2047 out_printf(outh, "#define %s_ARG_%s(arg) \t"
2049 macrobase, s, a->name);
2051 out_printf(outh, "#define %s_GET_ARG_%s(arg)\t"
2053 macrobase, s, a->name);
2061 print_ccode_block(CCode *cc)
2064 switch(cc->cctype) {
2066 /* HT code is printed exactly like normal header
2067 code but is printed before */
2070 out_printf(fp, "\n");
2073 /* AT code is printed exactly like normal 'all'
2074 code but is printed before */
2077 out_printf(outph, "\n");
2078 out_printf(outph, "%s\n", cc->cbuf);
2079 out_addline_infile(outph, cc->line_no);
2080 out_addline_outfile(outph);
2082 out_printf(outh, "\n");
2083 out_printf(outh, "%s\n", cc->cbuf);
2085 out_printf(fp, "\n");
2086 out_addline_infile(fp, cc->line_no);
2091 out_printf(fp, "\n");
2092 out_addline_infile(fp, cc->line_no);
2099 out_printf(fp, "\n");
2100 out_addline_infile(fp, cc->line_no);
2103 out_printf(fp, "%s\n", cc->cbuf);
2104 if(cc->cctype == C_CCODE ||
2105 cc->cctype == A_CCODE ||
2106 cc->cctype == AT_CCODE ||
2107 cc->cctype == PH_CCODE)
2108 out_addline_outfile(fp);
2112 print_class_block(Class *c)
2116 gboolean printed_private = FALSE;
2119 out_printf(out, "/* utility types we may need */\n");
2120 if(special_array[SPECIAL_2POINTER])
2121 out_printf(out, "typedef struct { "
2122 "gpointer a; gpointer b; "
2123 "} ___twopointertype;\n");
2124 if(special_array[SPECIAL_3POINTER])
2125 out_printf(out, "typedef struct { "
2126 "gpointer a; gpointer b; "
2128 "} ___threepointertype;\n");
2129 if(special_array[SPECIAL_INT_POINTER])
2130 out_printf(out, "typedef struct { "
2131 "gint a; gpointer b; "
2132 "} ___intpointertype;\n");
2133 out_printf(out, "\n");
2136 out_printf(outh, "\n/*\n"
2137 " * Type checking and casting macros\n"
2139 out_printf(outh, "#define %s\t"
2140 "(%s_get_type())\n",
2141 macrotype, funcbase);
2142 out_printf(outh, "#define %s(obj)\t"
2143 "GTK_CHECK_CAST((obj), %s_get_type(), %s)\n",
2144 macrobase, funcbase, typebase);
2145 out_printf(outh, "#define %s_CONST(obj)\t"
2146 "GTK_CHECK_CAST((obj), %s_get_type(), %s const)\n",
2147 macrobase, funcbase, typebase);
2148 out_printf(outh, "#define %s_CLASS(klass)\t"
2149 "GTK_CHECK_CLASS_CAST((klass), %s_get_type(), %sClass)\n",
2150 macrobase, funcbase, typebase);
2151 out_printf(outh, "#define %s(obj)\t"
2152 "GTK_CHECK_TYPE((obj), %s_get_type ())\n\n",
2154 out_printf(outh, "#ifdef GTK_CHECK_GET_CLASS\n"
2155 "#define %s_GET_CLASS(obj)\t"
2156 "GTK_CHECK_GET_CLASS((obj), %s_get_type(), %sClass)\n",
2157 macrobase, funcbase, typebase);
2158 out_printf(outh, "#else /* !GTK_CHECK_GET_CLASS */\n"
2159 "#define %s_GET_CLASS(obj)\t"
2160 "((%sClass *)GTK_OBJECT(obj)->klass)\n"
2161 "#endif /* GTK_CHECK_GET_CLASS */\n",
2162 macrobase, typebase);
2164 if( ! no_self_alias) {
2165 out_printf(out, "/* self casting macros */\n");
2166 out_printf(out, "#define SELF(x) %s(x)\n", macrobase);
2167 out_printf(out, "#define SELF_CONST(x) %s_CONST(x)\n", macrobase);
2168 out_printf(out, "#define IS_SELF(x) %s(x)\n", macrois);
2169 out_printf(out, "#define SELF_CLASS(x) %s_CLASS(x)\n\n",
2171 out_printf(out, "#define SELF_GET_CLASS(x) %s_GET_CLASS(x)\n\n",
2174 out_printf(out, "/* self typedefs */\n");
2175 out_printf(out, "typedef %s Self;\n", typebase);
2176 out_printf(out, "typedef %sClass SelfClass;\n\n", typebase);
2179 out_printf(out, "/* GTK_CLASS_TYPE for 1.2<->1.3/2.0 GTK+ compatibility */\n");
2181 "#ifndef GTK_CLASS_TYPE\n"
2182 "#define GTK_CLASS_TYPE(x) (GTK_OBJECT_CLASS(x)->type)\n"
2183 "#endif /* GTK_CLASS_TYPE */\n\n");
2185 if(privates > 0 || always_private_struct) {
2186 out_printf(outh, "\n/* Private structure type */\n");
2187 out_printf(outh, "typedef struct _%sPrivate %sPrivate;\n",
2188 typebase, typebase);
2190 out_printf(outh, "/* There are no privates, this "
2191 "structure is thus never defined */\n");
2194 out_printf(outh, "\n/*\n"
2195 " * Main object structure\n"
2197 s = replace_sep(c->otype, '_');
2199 out_printf(outh, "#ifndef __TYPEDEF_%s__\n"
2200 "#define __TYPEDEF_%s__\n", s, s);
2202 out_printf(outh, "typedef struct _%s %s;\n"
2203 "#endif\n", typebase, typebase);
2204 out_printf(outh, "struct _%s {\n\t%s __parent__;\n",
2205 typebase, ptypebase);
2206 for(l=c->nodes; l; l=g_list_next(l)) {
2207 static gboolean printed_public = FALSE;
2209 Variable *v = (Variable *)n;
2210 if(n->type == VARIABLE_NODE &&
2211 v->scope == PUBLIC_SCOPE) {
2212 if( ! printed_public) {
2213 out_printf(outh, "\t/*< public >*/\n");
2214 printed_public = TRUE;
2216 put_variable((Variable *)n, outh);
2219 /* put protecteds always AFTER publics */
2220 for(l=c->nodes; l; l=g_list_next(l)) {
2222 Variable *v = (Variable *)n;
2223 if(n->type == VARIABLE_NODE &&
2224 v->scope == PROTECTED_SCOPE) {
2225 if( ! printed_private) {
2226 out_printf(outh, "\t/*< private >*/\n");
2227 printed_private = TRUE;
2229 put_variable((Variable *)n, outh);
2232 if(privates > 0 || always_private_struct) {
2233 if( ! printed_private)
2234 out_printf(outh, "\t/*< private >*/\n");
2235 out_printf(outh, "\t%sPrivate *_priv;\n", typebase);
2237 out_printf(outh, "};\n");
2242 /* if we are to stick this into the private
2243 header, if not stick it directly into the
2250 out_printf(outfp, "struct _%sPrivate {\n",
2252 for(l=c->nodes; l; l=l->next) {
2254 Variable *v = (Variable *)n;
2255 if(n->type == VARIABLE_NODE &&
2256 v->scope == PRIVATE_SCOPE) {
2257 out_addline_infile(outfp, v->line_no);
2258 put_variable(v, outfp);
2261 out_addline_outfile(outfp);
2262 out_printf(outfp, "};\n");
2265 out_printf(outh, "\n/*\n"
2266 " * Class definition\n"
2268 out_printf(outh, "typedef struct _%sClass %sClass;\n",
2269 typebase, typebase);
2271 "struct _%sClass {\n\t%sClass __parent__;\n",
2272 typebase, ptypebase);
2273 for(l = c->nodes; l != NULL; l = l->next) {
2275 if(n->type == METHOD_NODE)
2276 put_vs_method((Method *)n);
2278 /* put class scope variables */
2279 for(l = c->nodes; l != NULL; l = l->next) {
2281 Variable *v = (Variable *)n;
2282 if(n->type == VARIABLE_NODE &&
2283 v->scope == CLASS_SCOPE)
2284 put_variable((Variable *)n, outh);
2286 out_printf(outh, "};\n\n");
2288 out_printf(out, "/* here are local prototypes */\n");
2289 if(set_arguments > 0) {
2290 out_printf(out, "static void ___object_set_arg "
2291 "(GtkObject *object, GtkArg *arg, "
2292 "guint arg_id);\n");
2294 if(get_arguments > 0) {
2295 out_printf(out, "static void ___object_get_arg "
2296 "(GtkObject *object, GtkArg *arg, "
2297 "guint arg_id);\n");
2300 out_printf(outh, "\n/*\n"
2301 " * Public methods\n"
2304 out_printf(outh, "GtkType\t%s_get_type\t(void)", funcbase);
2306 out_printf(outh, " G_GNUC_CONST;\n");
2308 out_printf(outh, ";\n");
2311 for(l = c->nodes; l != NULL; l = l->next) {
2313 if(n->type == METHOD_NODE) {
2314 put_pub_method((Method *)n);
2315 put_prot_method((Method *)n);
2316 put_priv_method_prot((Method *)n);
2320 /* this idea is less and less apealing to me */
2322 out_printf (outh, "\n/*\n"
2323 " * Signal connection wrapper macros\n"
2326 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
2327 put_signal_macros (c, TRUE);
2328 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
2329 put_signal_macros (c, FALSE);
2330 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n");
2332 put_signal_macros (c, FALSE);
2336 /* argument wrapping macros */
2337 if(get_arguments > 0 || set_arguments > 0) {
2338 out_printf(outh, "\n/*\n"
2339 " * Argument wrapping macros\n"
2342 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
2343 put_argument_gnu_wrappers(c);
2344 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
2345 put_argument_nongnu_wrappers(c);
2346 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n");
2348 put_argument_nongnu_wrappers(c);
2353 for(l = c->nodes; l != NULL; l = l->next) {
2355 if(n->type == METHOD_NODE)
2356 add_signal_prots((Method *)n);
2362 if ( ! overrode_get_type)
2365 if(any_method_to_alias(c)) {
2367 out_printf(out, "/* Short form macros */\n");
2368 out_printf(out, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
2369 make_method_gnu_aliases(c);
2370 out_printf(out, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n");
2372 make_method_nongnu_aliases(c);
2375 out_printf(out, "/* a macro for creating a new object of our type */\n");
2377 "#define GET_NEW ((%s *)gtk_type_new(%s_get_type()))\n\n",
2378 typebase, funcbase);
2388 if(set_arguments > 0) {
2389 add_getset_arg(c, TRUE);
2392 if(get_arguments > 0) {
2393 add_getset_arg(c, FALSE);
2396 for(l = c->nodes; l != NULL; l = l->next) {
2398 if(n->type == METHOD_NODE)
2399 put_method((Method *)n);
2402 add_bad_hack_to_avoid_unused_warnings(c);
2406 print_version_macros(void)
2408 int major=0, minor=0, pl=0;
2409 sscanf(VERSION, "%d.%d.%d", &major, &minor, &pl);
2411 out_printf(out, "#define GOB_VERSION_MAJOR %d\n", major);
2412 out_printf(out, "#define GOB_VERSION_MINOR %d\n", minor);
2413 out_printf(out, "#define GOB_VERSION_PATCHLEVEL %d\n\n", pl);
2417 print_file_comments(void)
2421 out_printf(outh, "/* Generated by GOB (v%s)"
2422 " (do not edit directly) */\n\n", VERSION);
2424 out_printf(outph, "/* Generated by GOB (v%s)"
2425 " (do not edit directly) */\n\n", VERSION);
2426 out_printf(out, "/* Generated by GOB (v%s) on %s"
2427 " (do not edit directly) */\n\n",
2428 VERSION, ctime(&curtime));
2430 out_printf(out, "/* End world hunger, donate to the World Food Programme, http://www.wfp.org */\n\n");
2434 print_includes(void)
2436 gboolean found_header;
2439 /* We may need string.h for memset */
2440 if(destructors > 0 &&
2441 ! g_list_find_custom(include_files, "string.h", (GCompareFunc)strcmp)) {
2442 out_printf(out, "#include <string.h> /* memset() */\n\n");
2445 p = g_strconcat(filebase, ".h", NULL);
2446 found_header = TRUE;
2447 if( ! g_list_find_custom(include_files, p, (GCompareFunc)strcmp)) {
2448 out_printf(out, "#include \"%s.h\"\n\n", filebase);
2449 found_header = FALSE;
2453 /* if we are creating a private header see if it was included */
2455 p = g_strconcat(filebase, "-private.h", NULL);
2456 if( ! g_list_find_custom(include_files, p,
2457 (GCompareFunc)strcmp)) {
2458 out_printf(out, "#include \"%s-private.h\"\n\n",
2461 error_printf(GOB_WARN, 0,
2462 "Implicit private header include "
2464 "\tsource file, while public "
2465 "header is at a custom location, "
2467 "\texplicitly include "
2468 "the private header below the "
2476 print_header_prefixes(void)
2480 p = replace_sep(((Class *)class)->otype, '_');
2482 out_printf(outh, "#ifndef __%s_H__\n#define __%s_H__\n\n", p, p);
2484 out_printf(outph, "#ifndef __%s_PRIVATE_H__\n"
2485 "#define __%s_PRIVATE_H__\n\n"
2486 "#include \"%s.h\"\n\n", p, p, filebase);
2489 if( ! no_extern_c) {
2490 out_printf(outh, "#ifdef __cplusplus\n"
2492 "#endif /* __cplusplus */\n\n");
2494 out_printf(outph, "#ifdef __cplusplus\n"
2496 "#endif /* __cplusplus */\n\n");
2501 print_header_postfixes(void)
2504 out_printf(outh, "\n#ifdef __cplusplus\n"
2506 "#endif /* __cplusplus */\n");
2507 out_printf(outh, "\n#endif\n");
2510 out_printf(outph, "\n#ifdef __cplusplus\n"
2512 "#endif /* __cplusplus */\n");
2513 out_printf(outph, "\n#endif\n");
2522 /* print the AT_CCODE blocks */
2523 for(li = nodes; li != NULL; li = li->next) {
2524 Node *node = li->data;
2525 if(node->type == CCODE_NODE) {
2526 CCode *cc = (CCode *)node;
2527 if(cc->cctype == AT_CCODE)
2528 print_ccode_block((CCode *)node);
2534 print_header_top(void)
2538 /* mandatory include */
2539 out_printf(outh, "#include <gtk/gtk.h>\n\n");
2541 /* print the HT_CCODE blocks */
2542 for(li=nodes;li;li=g_list_next(li)) {
2543 Node *node = li->data;
2544 if(node->type == CCODE_NODE) {
2545 CCode *cc = (CCode *)node;
2546 if(cc->cctype == HT_CCODE)
2547 print_ccode_block((CCode *)node);
2553 generate_outfiles(void)
2557 print_file_comments();
2563 print_header_prefixes();
2565 print_version_macros();
2569 for(li=nodes;li;li=g_list_next(li)) {
2570 Node *node = li->data;
2571 if(node->type == CCODE_NODE) {
2572 CCode *cc = (CCode *)node;
2573 if(cc->cctype != HT_CCODE &&
2574 cc->cctype != AT_CCODE)
2575 print_ccode_block((CCode *)node);
2576 } else if(node->type == CLASS_NODE) {
2577 print_class_block((Class *)node);
2579 g_assert_not_reached();
2582 print_header_postfixes();
2588 fprintf(stderr, "Gob version %s\n\n", VERSION);
2589 fprintf(stderr, "gob [options] file.gob\n\n");
2590 fprintf(stderr, "Options:\n"
2591 "\t--help,-h,-? Display this help\n"
2592 "\t--version Display version\n"
2593 "\t--exit-on-warn,-w Exit with an error on warnings\n"
2594 "\t--no-exit-on-warn Don't exit on warnings [default]\n"
2595 "\t--for-cpp Create C++ files\n"
2596 "\t--no-extern-c Never print extern \"C\" into the "
2598 "\t--no-gnu Never use GNU extentions\n"
2599 "\t--no-touch-headers Don't touch headers unless they "
2601 "\t--always-private-header Always create a private header "
2603 "\t even if it would be empty "
2605 "\t--ondemand-private-header Create private header only when "
2607 "\t--no-private-header Don't create a private header, "
2609 "\t structure and protected "
2610 "prototypes inside c file\n"
2611 "\t--always-private-struct Always create a private pointer "
2613 "\t the object structure\n"
2614 "\t--no-write,-n Don't write output files, just "
2616 "\t--no-lines Don't print '#line' to output\n"
2617 "\t--no-self-alias Don't create self type and macro "
2619 "\t--no-kill-underscores Don't remove the leading underscore "
2621 "\t short id names\n");
2625 parse_options(int argc, char *argv[])
2628 int got_file = FALSE;
2629 int no_opts = FALSE;
2633 for(i = 1 ; i < argc; i++) {
2635 argv[i][0] != '-') {
2638 fprintf(stderr, "Specify only one file!\n");
2644 } else if(strcmp(argv[i], "--help")==0) {
2647 } else if(strcmp(argv[i], "--version")==0) {
2648 fprintf(stderr, "Gob version %s\n", VERSION);
2650 } else if(strcmp(argv[i], "--exit-on-warn")==0) {
2651 exit_on_warn = TRUE;
2652 } else if(strcmp(argv[i], "--no-exit-on-warn")==0) {
2653 exit_on_warn = FALSE;
2654 } else if(strcmp(argv[i], "--for-cpp")==0) {
2656 } else if(strcmp(argv[i], "--no-touch-headers")==0) {
2657 no_touch_headers = TRUE;
2658 } else if(strcmp(argv[i], "--ondemand-private-header")==0) {
2659 private_header = PRIVATE_HEADER_ONDEMAND;
2660 } else if(strcmp(argv[i], "--always-private-header")==0) {
2661 private_header = PRIVATE_HEADER_ALWAYS;
2662 } else if(strcmp(argv[i], "--no-private-header")==0) {
2663 private_header = PRIVATE_HEADER_NEVER;
2664 } else if(strcmp(argv[i], "--no-gnu")==0) {
2666 } else if(strcmp(argv[i], "--no-extern-c")==0) {
2668 } else if(strcmp(argv[i], "--no-write")==0) {
2670 } else if(strcmp(argv[i], "--no-lines")==0) {
2672 } else if(strcmp(argv[i], "--no-self-alias")==0) {
2673 no_self_alias = TRUE;
2674 } else if(strcmp(argv[i], "--no-kill-underscores")==0) {
2675 no_kill_underscores = TRUE;
2676 } else if(strcmp(argv[i], "--always-private-struct")==0) {
2677 always_private_struct = TRUE;
2678 } else if(strcmp(argv[i], "--")==0) {
2679 /*further arguments are files*/
2681 } else if(strncmp(argv[i], "--", 2)==0) {
2682 /*unknown long option*/
2683 fprintf(stderr, "Unknown option '%s'!\n", argv[i]);
2687 /*by now we know we have a string starting with
2688 - which is a short option string*/
2690 for(p = argv[i] + 1; *p; p++) {
2704 "Unknown option '%c'!\n", *p);
2713 /* this is a somewhat ugly hack, but it appears to work */
2715 compare_and_move_header(void)
2717 char *hfnew = g_strconcat("#gob#", filebase, ".h#gob#", NULL);
2718 char *hf = g_strconcat(filebase, ".h", NULL);
2720 if(stat(hf, &s) == 0) {
2722 s = g_strdup_printf("cmp '%s' '%s' > /dev/null", hf, hfnew);
2723 if(system(s) == 0) {
2724 if(unlink(hfnew) != 0)
2725 error_printf(GOB_ERROR, 0,
2726 "Can't remove new header file");
2734 error_printf(GOB_ERROR, 0,
2735 "Can't remove old header file");
2737 if(rename(hfnew, hf) != 0)
2738 error_printf(GOB_ERROR, 0,
2739 "Can't rename new header file");
2745 main(int argc, char *argv[])
2747 parse_options(argc, argv);
2750 yyin = fopen(filename, "r");
2752 fprintf(stderr, "Error: can't open file '%s'\n",
2759 /* This is where parsing is done */
2762 g_error("Parsing errors, quitting");
2765 error_print(GOB_ERROR, 0, " no class defined");
2768 exit_on_error = FALSE;
2770 signals = count_signals((Class *)class);
2771 set_arguments = count_set_arguments((Class *)class);
2772 get_arguments = count_get_arguments((Class *)class);
2773 overrides = count_overrides((Class *)class);
2774 privates = count_privates((Class *)class);
2775 protecteds = count_protecteds((Class *)class);
2776 destructors = count_destructors((Class *)class);
2777 initializers = count_initializers((Class *)class);
2778 overrode_get_type = find_get_type((Class *)class);
2781 make_inits((Class *)class);
2782 if(destructors > 0) {
2783 need_destroy = TRUE;
2784 find_destroy((Class *)class);
2787 need_finalize = TRUE;
2788 find_finalize((Class *)class);
2790 check_bad_symbols((Class *)class);
2791 check_duplicate_symbols((Class *)class);
2792 check_duplicate_overrides((Class *)class);
2793 check_duplicate_signals_args((Class *)class);
2794 check_public_new((Class *)class);
2795 check_vararg((Class *)class);
2796 check_firstarg((Class *)class);
2797 check_nonvoidempty((Class *)class);
2798 check_signal_args((Class *)class);
2799 check_argument_types((Class *)class);
2800 check_func_arg_checks((Class *)class);
2802 exit_on_error = TRUE;
2807 any_special = setup_special_array((Class *)class, special_array);
2811 generate_outfiles();
2822 if(no_touch_headers &&
2824 compare_and_move_header();