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(const 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(const 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, const 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,
197 const char *typeprefix,
198 const char *nameprefix,
199 const char *subnameprefix,
200 const char *namepostfix,
201 const char *afterargs,
204 gboolean one_arg_per_line,
205 gboolean no_funcbase,
206 gboolean kill_underscore)
211 out_printf(fp, "%s", typeprefix);
212 print_type(fp, m->mtype, TRUE);
215 id = get_real_id(m->id);
220 out_printf(fp, "%s%s%s%s(",
221 nameprefix, subnameprefix, id, namepostfix);
223 out_printf(fp, "%s%s_%s%s%s(",
224 nameprefix, funcbase, subnameprefix, id,
228 for(li=m->args; li; li=g_list_next(li)) {
229 FuncArg *arg = li->data;
230 print_type(fp, arg->atype, FALSE);
232 out_printf(fp, "%s%s,%s", arg->name,
233 arg->atype->postfix ?
234 arg->atype->postfix : "",
235 one_arg_per_line ? "\n\t\t\t\t\t" : " ");
237 out_printf(fp, "%s%s", arg->name,
238 arg->atype->postfix ?
239 arg->atype->postfix : "");
242 out_printf(fp, ",%s...",
243 one_arg_per_line ? "\n\t\t\t\t\t" : " ");
245 out_printf(fp, "void");
247 out_printf(fp, "%s)%s", afterargs, postfix);
251 any_method_to_alias(Class *c)
255 for(li=c->nodes;li;li=g_list_next(li)) {
256 Node *node = li->data;
257 if(node->type == METHOD_NODE) {
258 Method *m = (Method *)node;
260 if(m->method == INIT_METHOD ||
261 m->method == CLASS_INIT_METHOD ||
262 m->method == OVERRIDE_METHOD)
272 /* just the vararg macros, we use the same func pointers for these as in non-gnu */
274 make_method_gnu_aliases(Class *c)
278 for(li = c->nodes; li != NULL; li = li->next) {
279 Node *node = li->data;
280 if(node->type == METHOD_NODE) {
281 Method *m = (Method *)node;
283 if(m->method == INIT_METHOD ||
284 m->method == CLASS_INIT_METHOD ||
285 m->method == OVERRIDE_METHOD)
288 /* in C++ mode don't alias new */
289 if(for_cpp && strcmp(m->id, "new")==0)
293 out_printf(out, "#define %s(args...) "
294 "%s_%s(args)\n", m->id,
295 funcbase, get_real_id(m->id));
297 out_printf(out, "#define %s() "
299 funcbase, get_real_id(m->id));
305 make_method_nongnu_aliases(Class *c)
309 gboolean local_made_aliases = FALSE;
311 for(li=c->nodes; li; li=g_list_next(li)) {
312 Node *node = li->data;
313 if(node->type == METHOD_NODE) {
314 Method *m = (Method *)node;
316 if(m->method == INIT_METHOD ||
317 m->method == CLASS_INIT_METHOD ||
318 m->method == OVERRIDE_METHOD)
321 /* in C++ mode don't alias new */
322 if(for_cpp && strcmp(m->id, "new")==0)
325 if( ! local_made_aliases)
326 out_printf(out, "\n/* Short form pointers */\n");
328 print_method(out, "static ", "(* const ", "", ") ",
330 m, FALSE, TRUE, FALSE);
331 out_printf(out, " = %s_%s;\n", funcbase,
334 local_made_aliases = TRUE;
337 if(local_made_aliases) {
338 out_printf(out, "\n");
344 add_bad_hack_to_avoid_unused_warnings(Class *c)
348 /* if we haven't had any methods, just return */
353 out_printf(out, "\n\n#if (!defined __GNUC__) || (defined __GNUC__ && defined __STRICT_ANSI__)\n");
355 "/*REALLY BAD HACK\n"
356 " This is to avoid unused warnings if you don't call\n"
357 " some method. I need to find a better way to do\n"
358 " this, not needed in GCC since we use some gcc\n"
359 " extentions to make saner, faster code */\n"
361 "___%s_really_bad_hack_to_avoid_warnings(void)\n"
363 for(li=c->nodes;li;li=g_list_next(li)) {
364 Node *node = li->data;
365 if(node->type == METHOD_NODE) {
366 Method *m = (Method *)node;
368 if(m->method == INIT_METHOD ||
369 m->method == CLASS_INIT_METHOD ||
370 m->method == OVERRIDE_METHOD)
373 /* in C++ mode we don't alias new */
374 if(for_cpp && strcmp(m->id, "new")==0)
377 out_printf(out, "\t((void (*)(void))%s)();\n", m->id);
380 out_printf(out, "\t___%s_really_bad_hack_to_avoid_warnings();\n",
383 out_printf(out, "}\n#endif /* !__GNUC__ || (__GNUC__ && __STRICT_ANSI__) */\n\n");
385 out_printf(out, "}\n\n");
389 put_variable(Variable *v, FILE *fp)
391 out_printf(fp, "\t");
392 print_type(fp, v->vtype, FALSE);
393 out_printf(fp, "%s%s;", v->id,
395 v->vtype->postfix:"");
396 if(v->scope == PROTECTED_SCOPE)
397 out_printf(fp, " /* protected */");
398 out_printf(fp, "\n");
402 put_vs_method(const Method *m)
404 if(m->method != SIGNAL_LAST_METHOD &&
405 m->method != SIGNAL_FIRST_METHOD &&
406 m->method != VIRTUAL_METHOD)
409 /* if a signal mark it as such */
410 if(m->method != VIRTUAL_METHOD)
411 print_method(outh, "\t/*signal*/", "(* ", "", ") ", "", ";\n",
412 m, FALSE, TRUE, TRUE);
414 print_method(outh, "\t", "(* ", "", ") ", "", ";\n",
415 m, FALSE, TRUE, TRUE);
419 put_pub_method(const Method *m)
421 if(m->scope != PUBLIC_SCOPE)
424 print_method(outh, "", "\t", "", "\t", "", ";\n", m, TRUE, FALSE, TRUE);
428 put_signal_macro (const Method *m, gboolean gnu)
432 if(m->method != SIGNAL_LAST_METHOD &&
433 m->method != SIGNAL_FIRST_METHOD)
436 id = g_strdup (m->id);
440 out_printf (outh, "#define %s_SIGNAL_%s(func)\t"
441 "\"%s\",GTK_SIGNAL_FUNC(func)\n",
442 macrobase, id, get_real_id (m->id));
444 out_printf (outh, "#define %s_SIGNAL_%s(func)\t"
445 "\"%s\",GTK_SIGNAL_FUNC(({",
446 macrobase, id, get_real_id (m->id));
447 print_method (outh, "", "(* ___", "", ") ", ", gpointer data ",
448 " = func; ", m, FALSE, TRUE, TRUE);
449 out_printf (outh, "___%s; }))\n", get_real_id (m->id));
456 put_signal_macros (const Class *c, gboolean gnu)
463 for (li = c->nodes; li != NULL; li = li->next) {
464 const Node *n = li->data;
465 if (n->type == METHOD_NODE)
466 put_signal_macro ((Method *)n, gnu);
472 put_prot_method(const Method *m)
474 if(m->scope != PROTECTED_SCOPE)
478 print_method(outph, "", "\t", "", "\t", "", ";\n",
479 m, FALSE, FALSE, TRUE);
481 print_method(out, "", "\t", "", "\t", "", ";\n",
482 m, FALSE, FALSE, TRUE);
486 put_priv_method_prot(Method *m)
488 if(m->method == SIGNAL_LAST_METHOD ||
489 m->method == SIGNAL_FIRST_METHOD ||
490 m->method == VIRTUAL_METHOD) {
493 "static ", "___real_", "", " ", "", ";\n",
494 m, FALSE, FALSE, TRUE);
496 /* no else, here, it might still have a private prototype, it's not
499 if((m->method == OVERRIDE_METHOD &&
502 char *s = g_strdup_printf("___%x_", (guint)m->unique_id);
503 print_method(out, "static ", s, "", " ", "",
504 no_gnu?";\n":" G_GNUC_UNUSED;\n",
505 m, FALSE, FALSE, FALSE);
507 } else if(m->scope == PRIVATE_SCOPE ||
508 m->method == INIT_METHOD ||
509 m->method == CLASS_INIT_METHOD)
510 print_method(out, "static ", "", "", " ", "",
511 no_gnu?";\n":" G_GNUC_UNUSED;\n",
512 m, FALSE, FALSE, TRUE);
516 make_func_arg(char *typename, int is_class, char *name)
523 tn = g_strconcat(typename, ":Class", NULL);
525 tn = g_strdup(typename);
527 type = new_type(tn, g_strdup("*"), NULL);
528 node = new_funcarg((Type *)type, name, NULL);
529 return g_list_prepend(NULL, node);
533 make_inits(Class *cl)
535 int got_class_init = FALSE;
536 int got_init = FALSE;
539 for(li=cl->nodes;li;li=g_list_next(li)) {
541 if(n->type == METHOD_NODE) {
542 Method *m = (Method *)n;
543 if(m->method == INIT_METHOD) {
545 error_print(GOB_ERROR, m->line_no, "init defined more then once");
547 } else if(m->method == CLASS_INIT_METHOD) {
549 error_print(GOB_ERROR, m->line_no, "class_init defined more then once");
550 got_class_init = TRUE;
554 if(!got_class_init) {
555 node = new_method(NO_SCOPE, CLASS_INIT_METHOD,
556 (Type *)new_type(g_strdup("void"),
558 NULL, NULL, NULL, g_strdup("class_init"),
559 make_func_arg(cl->otype, TRUE, g_strdup("c")),
560 NULL, NULL, NULL, 0, 0, FALSE,
562 cl->nodes = g_list_prepend(cl->nodes, node);
565 node = new_method(NO_SCOPE, INIT_METHOD,
566 (Type *)new_type(g_strdup("void"),
568 NULL, NULL, NULL, g_strdup("init"),
569 make_func_arg(cl->otype, FALSE, g_strdup("o")),
570 NULL, NULL, NULL, 0, 0, FALSE,
572 cl->nodes = g_list_prepend(cl->nodes, node);
577 find_destroy(Class *cl)
581 destroy_handler = NULL;
582 for(li=cl->nodes;li;li=g_list_next(li)) {
584 if(n->type == METHOD_NODE) {
585 Method *m = (Method *)n;
586 if(m->method == OVERRIDE_METHOD &&
587 strcmp(m->id, "destroy")==0) {
588 if(strcmp(m->otype, "Gtk:Object") != 0) {
589 error_print(GOB_ERROR, m->line_no,
590 "destroy method override "
591 "of class other then "
594 if(g_list_length(m->args) != 1) {
595 error_print(GOB_ERROR, m->line_no,
596 "destroy method override "
597 "with more then one "
608 find_finalize(Class *cl)
612 finalize_handler = NULL;
613 for(li=cl->nodes;li;li=g_list_next(li)) {
615 if(n->type == METHOD_NODE) {
616 Method *m = (Method *)n;
617 if(m->method == OVERRIDE_METHOD &&
618 strcmp(m->id, "finalize")==0) {
619 if(strcmp(m->otype, "Gtk:Object") != 0 &&
620 strcmp(m->otype, "G:Object") != 0) {
621 error_print(GOB_ERROR, m->line_no,
622 "finalize method override "
623 "of class other then "
624 "Gtk:Object (or G:Object"
627 if(g_list_length(m->args) != 1) {
628 error_print(GOB_ERROR, m->line_no,
629 "finalize method override "
630 "with more then one "
633 finalize_handler = m;
641 /* hash of method -> name of signal prototype */
642 static GHashTable *marsh = NULL;
644 /* list of methods with different signal prototypes,
645 we check this list if we can use a signal prototype of a
646 previous signal method, there are only uniques here */
647 static GList *eq_signal_methods = NULL;
649 /* compare a list of strings */
651 is_list_equal(GList *a, GList *b)
653 for(;a && b; a=a->next, b=b->next) {
654 if(strcmp(a->data, b->data)!=0) {
658 /* the the lists were different length */
665 find_same_type_signal(Method *m)
668 for(li=eq_signal_methods;li;li=li->next) {
669 Method *mm = li->data;
670 if(is_list_equal(mm->gtktypes, m->gtktypes))
677 print_signal_marsal_args(Method *m)
679 if(strcmp(m->gtktypes->next->data, "NONE")!=0) {
682 for(i=0, li=m->gtktypes->next;li;
683 i++, li=g_list_next(li)) {
685 out_printf(out, ",\n\t\tGTK_VALUE_%s(args[%d])",
686 (char *)li->data, i);
688 out_printf(out, ",\n\t\t(%s)"
689 "GTK_VALUE_%s(args[%d])",
690 get_cast(li->data, FALSE),
691 (char *)li->data, i);
695 out_printf(out, ",\n\t\tfunc_data);\n}\n\n");
700 add_signal_prots(Method *m)
707 if(m->method != SIGNAL_LAST_METHOD &&
708 m->method != SIGNAL_FIRST_METHOD)
712 marsh = g_hash_table_new(NULL, NULL);
714 if(strcmp(m->gtktypes->data, "NONE")==0 &&
715 strcmp(m->gtktypes->next->data, "NONE")==0)
718 /* if we already did a signal prototype just use that */
719 mm = find_same_type_signal(m);
721 s = g_hash_table_lookup(marsh, mm);
722 g_hash_table_insert(marsh, m, s);
726 s = g_strdup_printf("Sig%d", sig++);
728 g_hash_table_insert(marsh, m, s);
729 eq_signal_methods = g_list_prepend(eq_signal_methods, m);
731 /* we know that we'll know all the gtktypes (so get_cast can't fail) */
732 out_printf(out, "\ntypedef %s (*___%s) (%s *, ",
733 get_cast(m->gtktypes->data, FALSE), s, typebase);
735 if(strcmp(m->gtktypes->next->data, "NONE")!=0) {
736 for(li=m->gtktypes->next; li; li=g_list_next(li))
737 out_printf(out, "%s, ", get_cast(li->data, FALSE));
739 out_printf(out, "gpointer);\n");
741 out_printf(out, "\nstatic void\n"
742 "___marshal_%s (GtkObject * object,\n"
743 "\tGtkSignalFunc func,\n"
744 "\tgpointer func_data,\n"
748 if(strcmp(m->gtktypes->data, "NONE")==0) {
749 out_printf(out, "\t___%s rfunc;\n\n"
750 "\trfunc = (___%s)func;\n\n"
751 "\t(*rfunc)((%s *)object", s, s, typebase);
753 const char *retcast = get_cast(m->gtktypes->data, FALSE);
757 "\trfunc = (___%s)func;\n\n"
758 "\tretval = GTK_RETLOC_%s(args[%d]);\n\n"
759 "\t*retval = (*rfunc)((%s *)object",
760 s, retcast, s, (char *)m->gtktypes->data,
761 g_list_length(m->gtktypes)-1, typebase);
763 print_signal_marsal_args(m);
771 out_printf(out, "\n");
773 out_printf(out, "enum {\n");
774 for(li=c->nodes;li;li=g_list_next(li)) {
776 if(n->type == METHOD_NODE) {
777 Method *m = (Method *)n;
778 if(m->method == SIGNAL_LAST_METHOD ||
779 m->method == SIGNAL_FIRST_METHOD) {
780 char *s = g_strdup(get_real_id(m->id));
782 out_printf(out, "\t%s_SIGNAL,\n", s);
787 out_printf(out, "\tLAST_SIGNAL\n};\n\n");
789 if(set_arguments > 0 || get_arguments > 0) {
790 out_printf(out, "enum {\n\tARG_0");
791 for(li=c->nodes;li;li=g_list_next(li)) {
793 if(n->type == ARGUMENT_NODE) {
794 Argument *a = (Argument *)n;
795 char *s = g_strdup(a->name);
797 out_printf(out, ",\n\tARG_%s", s);
801 out_printf(out, "\n};\n\n");
806 "static guint object_signals[LAST_SIGNAL] = {0};\n\n");
808 out_printf(out, "/* pointer to the class of our parent */\n");
809 out_printf(out, "static %sClass *parent_class = NULL;\n\n", ptypebase);
815 char *chunk_size = ((Class*)class)->chunk_size;
819 "%s_get_type (void)\n"
821 "\tstatic guint type = 0;\n\n"
823 "\t\tstatic const GtkTypeInfo info = {\n"
825 "\t\t\tsizeof (%s),\n"
826 "\t\t\tsizeof (%sClass),\n"
827 "\t\t\t(GtkClassInitFunc) %s_class_init,\n"
828 "\t\t\t(GtkObjectInitFunc) %s_init,\n"
829 "\t\t\t/* reserved_1 */ NULL,\n"
830 "\t\t\t/* reserved_2 */ NULL,\n"
831 "\t\t\t(GtkClassInitFunc) NULL\n"
833 "\t\ttype = gtk_type_unique (%s_get_type(), &info);\n",
834 funcbase, typebase, typebase, typebase,
835 funcbase, funcbase, pfuncbase);
839 "\t\tgtk_type_set_chunk_alloc(type, %s);\n"
841 chunk_size, chunk_size);
850 add_overrides(Class *c, const char *oname, gboolean did_base_obj)
856 done = g_hash_table_new(g_str_hash, g_str_equal);
858 s = g_strdup("GtkObject"); /* This was already done */
859 g_hash_table_insert(done, s, s);
860 s = g_strdup("GObject"); /* This was probably already done as well (if using Gtk/Glib 1.3/2.0) */
861 g_hash_table_insert(done, s, s);
863 for(li=c->nodes; li; li=g_list_next(li)) {
866 Method *m = (Method *)n;
867 if(n->type != METHOD_NODE ||
868 m->method != OVERRIDE_METHOD)
871 s = remove_sep(m->otype);
873 if(g_hash_table_lookup(done, s)) {
877 g_hash_table_insert(done, s, s);
879 f = replace_sep(m->otype, '_');
882 out_printf(out, "\t%sClass *%s_class = (%sClass *)%s;\n",
887 g_hash_table_foreach(done, (GHFunc)g_free, NULL);
888 g_hash_table_destroy(done);
892 make_run_signal_flags(Method *m, gboolean last)
906 gs = g_string_new(NULL);
909 g_string_assign(gs, "GTK_RUN_LAST");
911 g_string_assign(gs, "GTK_RUN_FIRST");
913 if(m->scope == PUBLIC_SCOPE)
914 g_string_append(gs, " | GTK_RUN_ACTION");
916 for(li = m->flags; li; li = li->next) {
917 char *flag = li->data;
919 for(i=0;flags[i];i++) {
920 if(strcmp(flags[i], flag)==0)
923 /* if we haven't found it in our list */
925 error_printf(GOB_WARN, m->line_no,
926 "Unknown flag '%s' used, "
927 "perhaps it was misspelled",
930 g_string_sprintfa(gs, " | GTK_RUN_%s", flag);
935 g_string_free(gs, FALSE);
942 add_signals(Class *c)
946 out_printf(out, "\n");
947 for(li=c->nodes;li;li=g_list_next(li)) {
949 char *mar, *sig, *flags;
950 gboolean is_none, last = FALSE;
951 Method *m = (Method *)n;
953 if(n->type != METHOD_NODE ||
954 (m->method != SIGNAL_FIRST_METHOD &&
955 m->method != SIGNAL_LAST_METHOD))
958 if(m->method == SIGNAL_FIRST_METHOD)
963 if(g_hash_table_lookup(marsh, m))
964 mar = g_strconcat("___marshal_",
965 (char *)g_hash_table_lookup(marsh, m),
968 mar = g_strdup("gtk_signal_default_marshaller");
970 is_none = (strcmp(m->gtktypes->next->data, "NONE")==0);
972 sig = g_strdup(get_real_id(m->id));
974 flags = make_run_signal_flags(m, last);
975 out_printf(out, "\tobject_signals[%s_SIGNAL] =\n"
976 "\t\tgtk_signal_new (\"%s\",\n"
977 "\t\t\t(GtkSignalRunType)(%s),\n"
978 "\t\t\tGTK_CLASS_TYPE(gtk_object_class),\n"
979 "\t\t\tGTK_SIGNAL_OFFSET (%sClass, %s),\n"
981 "\t\t\tGTK_TYPE_%s, %d",
982 sig, get_real_id(m->id),
984 typebase, get_real_id(m->id), mar,
985 (char *)m->gtktypes->data,
986 is_none ? 0 : g_list_length(m->gtktypes->next));
993 for(l = m->gtktypes->next; l != NULL; l = l->next)
994 out_printf(out, ",\n\t\t\tGTK_TYPE_%s",
998 out_printf(out, ");\n");
1000 if(strcmp(m->gtktypes->data, "NONE") != 0 ||
1004 out_printf(out, "\tif(");
1005 if(strcmp(m->gtktypes->data, "NONE") != 0) {
1006 out_printf(out, "%s sizeof(", sep);
1007 print_type(out, m->mtype, FALSE);
1008 out_printf(out, "%s",
1010 m->mtype->postfix : "");
1011 out_printf(out, ") != sizeof(%s)",
1012 get_cast(m->gtktypes->data, FALSE));
1017 for(al = m->args->next, gl = m->gtktypes->next;
1018 al != NULL && gl != NULL;
1019 al = al->next, gl = gl->next) {
1020 FuncArg *arg = al->data;
1021 char *gtkarg = gl->data;
1023 out_printf(out, "%ssizeof(", sep);
1024 print_type(out, arg->atype, FALSE);
1025 out_printf(out, "%s",
1026 arg->atype->postfix ?
1027 arg->atype->postfix : "");
1028 out_printf(out, ") != sizeof(%s)",
1029 get_cast(gtkarg, FALSE));
1033 out_printf(out, ") {\n"
1034 "\t\tg_error(\"%s line %d: Type mismatch "
1035 "of \\\"%s\\\" signal signature\");\n"
1037 filename, m->line_no, get_real_id(m->id));
1041 out_printf(out, "\tgtk_object_class_add_signals (gtk_object_class,\n"
1042 "\t\tobject_signals, LAST_SIGNAL);\n\n");
1046 set_def_handlers(Class *c, const char *oname)
1049 gboolean set_line = FALSE;
1051 out_printf(out, "\n");
1052 for(li = c->nodes; li; li = g_list_next(li)) {
1054 Method *m = (Method *)n;
1056 if(n->type != METHOD_NODE ||
1057 (m->method != SIGNAL_FIRST_METHOD &&
1058 m->method != SIGNAL_LAST_METHOD &&
1059 m->method != VIRTUAL_METHOD &&
1060 m->method != OVERRIDE_METHOD))
1063 if(m->line_no > 0 && m->cbuf) {
1064 out_addline_infile(out, m->line_no);
1066 } else if(set_line) {
1067 out_addline_outfile(out);
1072 if(m->method == OVERRIDE_METHOD) {
1074 s = replace_sep(m->otype, '_');
1079 strcmp(get_real_id(m->id), "destroy") == 0)
1080 out_printf(out, "\tgtk_object_class->destroy "
1082 else if(need_finalize &&
1084 strcmp(get_real_id(m->id), "finalize") == 0)
1086 "#ifdef G_OBJECT_CLASS\n"
1087 "\tg_object_class->finalize = ___finalize;\n"
1088 "#else /* !G_OBJECT_CLASS */\n"
1089 "\tgtk_object_class->finalize = ___finalize;\n"
1090 "#endif /* G_OBJECT_CLASS */\n");
1093 "\t%s_class->%s = ___%x_%s_%s;\n",
1094 s, get_real_id(m->id), (guint)m->unique_id,
1095 funcbase, get_real_id(m->id));
1097 out_printf(out, "\t%s_class->%s = NULL;\n",
1098 s, get_real_id(m->id));
1101 out_printf(out, "\t%s->%s = ___real_%s_%s;\n",
1102 oname, get_real_id(m->id),
1103 funcbase, get_real_id(m->id));
1105 out_printf(out, "\t%s->%s = NULL;\n",
1106 oname, get_real_id(m->id));
1110 out_addline_outfile(out);
1114 make_arguments(Class *c)
1117 char *argflags[] = {
1125 out_printf(out, "\n");
1126 for(li=c->nodes;li;li=g_list_next(li)) {
1132 if(n->type != ARGUMENT_NODE)
1137 if(a->get && a->set)
1138 flags = g_string_new("GTK_ARG_READWRITE");
1140 flags = g_string_new("GTK_ARG_READABLE");
1142 flags = g_string_new("GTK_ARG_WRITABLE");
1144 g_assert(a->get || a->set);
1146 for(l=a->flags;l;l=g_list_next(l)) {
1147 char *flag = l->data;
1149 if(strcmp(flag, "READWRITE")==0 ||
1150 strcmp(flag, "READABLE")==0 ||
1151 strcmp(flag, "WRITABLE")==0) {
1152 error_print(GOB_WARN, a->line_no,
1153 "READWRITE, READABLE and "
1154 "WRITABLE argument flags are "
1155 "set automatically");
1158 for(i = 0; argflags[i]; i++) {
1159 if(strcmp(argflags[i], flag)==0)
1162 /* if we haven't found it in our list */
1163 if( ! argflags[i]) {
1164 error_printf(GOB_WARN, a->line_no,
1165 "Unknown flag '%s' used, "
1166 "perhaps it was misspelled", flag);
1168 g_string_sprintfa(flags, " | GTK_ARG_%s", flag);
1171 s = g_strdup(a->name);
1173 out_printf(out, "\tgtk_object_add_arg_type(\"%s::%s\",\n"
1174 "\t\tGTK_TYPE_%s,\n"
1177 typebase, a->name, a->gtktype, flags->str, s);
1179 g_string_free(flags, TRUE);
1182 out_printf(out, "\n");
1183 if(get_arguments > 0)
1184 out_printf(out, "\tgtk_object_class->get_arg = ___object_get_arg;\n");
1185 if(set_arguments > 0)
1186 out_printf(out, "\tgtk_object_class->set_arg = ___object_set_arg;\n");
1190 print_initializer(Method *m, Variable *v)
1194 if(v->initializer == NULL)
1197 if(v->scope == PRIVATE_SCOPE)
1198 root = g_strconcat(((FuncArg *)m->args->data)->name,
1201 root = g_strdup(((FuncArg *)m->args->data)->name);
1203 if(v->initializer_line > 0)
1204 out_addline_infile(out, v->initializer_line);
1206 out_printf(out, "\t%s->%s = %s;\n",
1207 root, v->id, v->initializer);
1209 if(v->initializer_line > 0)
1210 out_addline_outfile(out);
1216 print_destructor(Variable *v)
1220 if(v->destructor == NULL)
1223 if(v->scope == PRIVATE_SCOPE)
1224 root = "self->_priv";
1228 if(v->destructor_simple) {
1229 if(v->destructor_line > 0)
1230 out_addline_infile(out, v->destructor_line);
1232 out_printf(out, "\tif(%s->%s) { "
1233 "((*(void (*)(void *))%s)) (%s->%s); "
1234 "%s->%s = NULL; }\n",
1235 root, v->id, v->destructor, root, v->id,
1238 if(v->destructor_line > 0)
1239 out_addline_outfile(out);
1241 out_printf(out, "#define VAR (%s->%s)\n", root, v->id);
1242 out_printf(out, "\t{\n");
1243 if(v->destructor_line > 0)
1244 out_addline_infile(out, v->destructor_line);
1246 out_printf(out, "\t%s}\n", v->destructor);
1248 if(v->destructor_line > 0)
1249 out_addline_outfile(out);
1250 out_printf(out, "\tmemset(&VAR, 0, sizeof(VAR));\n");
1251 out_printf(out, "#undef VAR\n");
1256 add_destroy(Class *c)
1258 out_printf(out, "\nstatic void\n"
1259 "___destroy(GtkObject *obj_self)\n"
1262 "#define __GOB_FUNCTION__ \"%s::destroy\"\n",
1265 if(destructors > 0) {
1266 out_printf(out, "\t%s *self = %s (obj_self);\n",
1267 typebase, macrobase);
1270 if(destroy_handler) {
1271 /* so we get possible bad argument warning */
1272 if(destroy_handler->line_no > 0)
1273 out_addline_infile(out, destroy_handler->line_no);
1274 out_printf(out, "\t___%x_%s_destroy(obj_self);\n",
1275 (guint)destroy_handler->unique_id, funcbase);
1276 if(destroy_handler->line_no > 0)
1277 out_addline_outfile(out);
1280 "\tif(GTK_OBJECT_CLASS(parent_class)->destroy) \\\n"
1281 "\t\t(* GTK_OBJECT_CLASS(parent_class)->destroy)(obj_self);\n");
1284 if(destructors > 0) {
1286 for(li = ((Class *)class)->nodes;
1290 Variable *v = (Variable *)n;
1291 if(n->type == VARIABLE_NODE &&
1292 v->scope != CLASS_SCOPE)
1293 print_destructor(v);
1297 out_printf(out, "\treturn;\n");
1299 out_printf(out, "\tself = NULL;\n");
1300 out_printf(out, "}\n"
1301 "#undef __GOB_FUNCTION__\n\n");
1305 add_finalize(Class *c)
1307 /* Sort of a hack to make it work with gtk+ 1.3/2.0 */
1309 "\n#ifdef G_OBJECT_CLASS\n"
1311 "___finalize(GObject *obj_self)\n"
1312 "#else /* !G_OBJECT_CLASS */\n"
1314 "___finalize(GtkObject *obj_self)\n"
1315 "#endif /* G_OBJECT_CLASS */\n"
1318 "#define __GOB_FUNCTION__ \"%s::finalize\"\n",
1322 out_printf(out, "\t%s *self = %s (obj_self);\n",
1323 typebase, macrobase);
1324 out_printf(out, "\tgpointer priv = self->_priv;\n");
1327 if(finalize_handler) {
1328 /* so we get possible bad argument warning */
1329 if(finalize_handler->line_no > 0)
1330 out_addline_infile(out, finalize_handler->line_no);
1331 out_printf(out, "\t___%x_%s_finalize(obj_self);\n",
1332 (guint)finalize_handler->unique_id, funcbase);
1333 if(finalize_handler->line_no > 0)
1334 out_addline_outfile(out);
1336 /* Sort of a hack to make it work with gtk+ 1.3/2.0 */
1338 "#ifdef G_OBJECT_CLASS\n"
1339 "\tif(G_OBJECT_CLASS(parent_class)->finalize) \\\n"
1340 "\t\t(* G_OBJECT_CLASS(parent_class)->finalize)(obj_self);\n"
1341 "#else /* !G_OBJECT_CLASS */\n"
1342 "\tif(GTK_OBJECT_CLASS(parent_class)->finalize) \\\n"
1343 "\t\t(* GTK_OBJECT_CLASS(parent_class)->finalize)(obj_self);\n"
1344 "#endif /* G_OBJECT_CLASS */\n");
1348 out_printf(out, "\tg_free(priv);\n");
1351 out_printf(out, "}\n"
1352 "#undef __GOB_FUNCTION__\n\n");
1359 for(li=c->nodes;li;li=g_list_next(li)) {
1363 gboolean add_unused_class = FALSE;
1365 if(n->type != METHOD_NODE)
1368 if(m->method == INIT_METHOD) {
1370 out_addline_infile(out, m->line_no);
1371 print_method(out, "static ", "\n", "", " ", "", "\n",
1372 m, FALSE, FALSE, TRUE);
1374 out_addline_outfile(out);
1375 out_printf(out, "{\n"
1376 "#define __GOB_FUNCTION__ \"%s::init\"\n",
1379 out_printf(out, "\t%s->_priv = "
1380 "g_new0 (%sPrivate, 1);\n",
1381 ((FuncArg *)m->args->data)->name,
1383 } else if(always_private_struct) {
1384 out_printf(out, "\t%s->_priv = NULL;\n",
1385 ((FuncArg *)m->args->data)->name);
1387 if(initializers > 0) {
1389 for(li = ((Class *)class)->nodes;
1393 Variable *v = (Variable *)n;
1394 if(n->type != VARIABLE_NODE ||
1395 v->scope == CLASS_SCOPE)
1397 print_initializer(m, v);
1400 } else if(m->method == CLASS_INIT_METHOD) {
1401 gboolean did_base_obj = FALSE;
1404 out_addline_infile(out, m->line_no);
1405 print_method(out, "static ", "\n", "", " ", "", "\n",
1406 m, FALSE, FALSE, TRUE);
1408 out_addline_outfile(out);
1409 out_printf(out, "{\n"
1410 "#define __GOB_FUNCTION__ \"%s::class_init\"\n",
1413 set_arguments > 0 ||
1414 get_arguments > 0 ||
1417 add_unused_class = TRUE;
1419 "\tGtkObjectClass *"
1420 "gtk_object_class = "
1421 "(GtkObjectClass*) %s;\n",
1422 ((FuncArg *)m->args->data)->name);
1424 "#ifdef G_OBJECT_CLASS\n"
1427 "(GObjectClass*) %s;\n"
1428 "#endif /* G_OBJECT_CLASS */\n",
1429 ((FuncArg *)m->args->data)->name);
1430 did_base_obj = TRUE;
1435 ((FuncArg *)m->args->data)->name,
1438 if(initializers > 0) {
1440 for(li = ((Class *)class)->nodes;
1444 Variable *v = (Variable *)n;
1445 if(n->type == VARIABLE_NODE &&
1446 v->scope == CLASS_SCOPE)
1447 print_initializer(m, v);
1451 out_printf(out, "\n\tparent_class = ");
1453 out_printf(out, "(%sClass *)", ptypebase);
1454 out_printf(out, "gtk_type_class (%s_get_type ());\n",
1460 set_def_handlers(c, ((FuncArg *)m->args->data)->name);
1462 /* if there are no handlers for these things, we
1463 * need to set them up here */
1464 if(need_destroy && !destroy_handler)
1465 out_printf(out, "\tgtk_object_class->destroy "
1467 if(need_finalize && !finalize_handler)
1469 "#ifdef G_OBJECT_CLASS\n"
1470 "\tg_object_class->finalize = ___finalize;\n"
1471 "#else /* !G_OBJECT_CLASS */\n"
1472 "\tgtk_object_class->finalize = ___finalize;\n"
1473 "#endif /* G_OBJECT_CLASS */\n");
1475 if(get_arguments > 0 || set_arguments > 0)
1482 out_printf(out, " {\n");
1483 out_addline_infile(out, m->ccode_line);
1484 out_printf(out, "%s\n", m->cbuf);
1485 out_addline_outfile(out);
1486 out_printf(out, " }\n");
1488 out_printf(out, "\treturn;\n");
1491 ((FuncArg *)m->args->data)->name);
1492 if(add_unused_class) {
1494 "\tgtk_object_class = NULL;\n"
1495 "#ifdef G_OBJECT_CLASS\n"
1496 "\tg_object_class = NULL;\n"
1497 "#endif /* G_OBJECT_CLASS */\n");
1499 out_printf(out, "}\n"
1500 "#undef __GOB_FUNCTION__\n");
1505 add_getset_arg(Class *c, gboolean is_set)
1508 out_printf(out, "\nstatic void\n"
1509 "___object_%s_arg (GtkObject *object,\n"
1512 "#define __GOB_FUNCTION__ \"%s::%s_arg\"\n"
1515 "\tself = %s (object);\n\n"
1516 "\tswitch (arg_id) {\n",
1517 is_set ? "set" : "get",
1518 c->otype, is_set ? "set" : "get",
1519 typebase, macrobase);
1521 for(li=c->nodes;li;li=g_list_next(li)) {
1527 if(n->type != ARGUMENT_NODE)
1532 line_no = a->set_line;
1535 line_no = a->get_line;
1539 s = g_strdup(a->name);
1541 out_printf(out, "\tcase ARG_%s:\n", s);
1542 if(is_set && a->atype) {
1543 char *cast = get_type(a->atype, TRUE);
1544 if(no_gnu || for_cpp) {
1545 out_printf(out, "#define ARG "
1546 "((%s)GTK_VALUE_%s(*arg))\n",
1549 out_printf(out, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
1550 if(strcmp(a->gtktype, "OBJECT")==0) {
1551 out_printf(out, "#define ARG "
1553 "GTK_VALUE_POINTER(*arg); "
1557 out_printf(out, "#define ARG "
1559 "GTK_VALUE_%s(*arg); "
1563 out_printf(out, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
1564 out_printf(out, "#define ARG "
1565 "((%s)GTK_VALUE_%s(*arg))\n",
1567 out_printf(out, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n");
1569 out_printf(out, "\t\t{\n");
1571 } else if(!is_set && strcmp(a->gtktype, "OBJECT")==0) {
1573 "#define ARG (GTK_VALUE_POINTER(*arg))\n"
1577 "#define ARG (GTK_VALUE_%s(*arg))\n"
1583 out_addline_infile(out, line_no);
1584 out_printf(out, "%s\n", cbuf);
1586 out_addline_outfile(out);
1587 out_printf(out, "\t\t}\n\t\tbreak;\n"
1590 out_printf(out, "\tdefault:\n\t\tbreak;\n\t}\n"
1591 "\treturn;\n\tself = NULL;\n\targ = NULL;\n}\n"
1592 "#undef __GOB_FUNCTION__\n");
1596 print_checks(Method *m, FuncArg *fa)
1600 gboolean checked_null = FALSE;
1601 is_void = (strcmp(m->mtype->name, "void")==0 &&
1602 m->mtype->pointer == NULL);
1604 for(li = fa->checks; li; li = g_list_next(li)) {
1605 Check *ch = li->data;
1607 /* point to the method prot in .gob for failed checks */
1609 out_addline_infile(out, m->line_no);
1611 out_printf(out, "\tg_return_if_fail (");
1613 out_printf(out, "\tg_return_val_if_fail (");
1614 switch(ch->chtype) {
1616 out_printf(out, "%s != NULL", fa->name);
1617 checked_null = TRUE;
1620 s = make_pre_macro(fa->atype->name, "IS");
1622 out_printf(out, "%s (%s)", s, fa->name);
1624 /* if not check null, null may be valid */
1625 out_printf(out, "!(%s) || %s (%s)", fa->name,
1630 out_printf(out, "%s < %s", fa->name, ch->number);
1633 out_printf(out, "%s > %s", fa->name, ch->number);
1636 out_printf(out, "%s <= %s", fa->name, ch->number);
1639 out_printf(out, "%s >= %s", fa->name, ch->number);
1642 out_printf(out, "%s == %s", fa->name, ch->number);
1645 out_printf(out, "%s != %s", fa->name, ch->number);
1649 out_printf(out, ");\n");
1651 out_printf(out, ", (");
1652 print_type(out, m->mtype, TRUE);
1653 out_printf(out, ")%s);\n",
1654 m->onerror?m->onerror:"0");
1660 print_preconditions(Method *m)
1664 for(li=m->args;li;li=g_list_next(li)) {
1665 FuncArg *fa = li->data;
1667 print_checks(m, fa);
1670 out_addline_outfile(out);
1674 print_method_body(Method *m, int pre)
1676 out_printf(out, "{\n"
1677 "#define __GOB_FUNCTION__ \"%s::%s\"\n",
1678 ((Class *)class)->otype,
1679 get_real_id(m->id));
1681 print_preconditions(m);
1683 /* Note: the trailing }'s are on one line, this is so
1684 that we get the no return warning correctly and point to
1685 the correct line in the .gob file, yes this is slightly
1686 ugly in the .c file, but that is not supposed to be
1687 human readable anyway. */
1689 out_printf(out, "{\n");
1691 out_addline_infile(out, m->ccode_line);
1692 out_printf(out, "\t%s}", m->cbuf);
1695 /* Note, there is no \n between the last } and this } so that
1696 * errors/warnings reported on the end of the body get pointed to the
1697 * right line in the .gob source */
1698 out_printf(out, "}\n");
1701 out_addline_outfile(out);
1702 out_printf(out, "#undef __GOB_FUNCTION__\n");
1706 put_signal_args(Method *m)
1710 for(ali = m->gtktypes->next, li=m->args->next;
1712 li=li->next, ali=ali->next) {
1713 FuncArg *fa = li->data;
1714 const char *cast = get_cast(ali->data, FALSE);
1715 /* we should have already proved before that
1716 the we know all the types */
1719 out_printf(out, ",\n\t\t(%s)%s", cast,
1725 get_arg_names_for_macro(Method *m)
1729 GString *gs = g_string_new(NULL);
1731 for(li=m->args;li;li=g_list_next(li)) {
1732 FuncArg *arg = li->data;
1733 g_string_sprintfa(gs, "%s___%s", p, arg->name);
1737 g_string_free(gs, FALSE);
1742 put_method(Method *m)
1744 char *s, *args, *doc;
1746 is_void = (strcmp(m->mtype->name, "void")==0 &&
1747 m->mtype->pointer == NULL);
1748 out_printf(out, "\n");
1749 if(m->method != OVERRIDE_METHOD) {
1750 doc = get_gtk_doc(m->id);
1752 out_printf(out, "%s", doc);
1757 case REGULAR_METHOD:
1759 out_addline_infile(out, m->line_no);
1760 if(m->scope == PRIVATE_SCOPE)
1761 print_method(out, "static ", "\n", "", " ", "", "\n",
1762 m, FALSE, FALSE, TRUE);
1763 else /* PUBLIC, PROTECTED */
1764 print_method(out, "", "\n", "", " ", "", "\n",
1765 m, FALSE, FALSE, TRUE);
1766 print_method_body(m, TRUE);
1767 /* the outfile line was added above */
1769 case SIGNAL_FIRST_METHOD:
1770 case SIGNAL_LAST_METHOD:
1772 out_addline_infile(out, m->line_no);
1773 if(m->scope == PRIVATE_SCOPE)
1774 print_method(out, "static ", "\n", "", " ", "", "\n",
1775 m, FALSE, FALSE, TRUE);
1776 else /* PUBLIC, PROTECTED */
1777 print_method(out, "", "\n", "", " ", "", "\n",
1778 m, FALSE, FALSE, TRUE);
1779 out_addline_outfile(out);
1780 out_printf(out, "{\n");
1781 s = g_strdup(get_real_id(m->id));
1783 if(strcmp(m->mtype->name, "void") == 0 &&
1784 m->mtype->pointer == NULL) {
1785 print_preconditions(m);
1786 if(((FuncArg *)m->args->data)->name)
1787 out_printf(out, "\tgtk_signal_emit (GTK_OBJECT (%s),\n"
1788 "\t\tobject_signals[%s_SIGNAL]",
1789 ((FuncArg *)m->args->data)->name, s);
1791 out_printf(out, ");\n}\n");
1793 out_printf(out, "\t");
1794 print_type(out, m->mtype, TRUE);
1795 out_printf(out, "return_val = (");
1796 print_type(out, m->mtype, TRUE);
1798 out_printf(out, ")(%s);\n", m->defreturn);
1800 out_printf(out, ")(%s);\n", m->onerror);
1802 out_printf(out, ")(0);\n");
1803 print_preconditions(m);
1804 out_printf(out, "\tgtk_signal_emit (GTK_OBJECT (%s),\n"
1805 "\t\tobject_signals[%s_SIGNAL]",
1806 ((FuncArg *)m->args->data)->name, s);
1808 out_printf(out, ",\n\t\t&return_val);\n"
1809 "\treturn return_val;\n}\n");
1815 out_addline_infile(out, m->line_no);
1816 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
1817 m, FALSE, FALSE, TRUE);
1818 print_method_body(m, FALSE);
1819 /* the outfile line was added above */
1821 case VIRTUAL_METHOD:
1823 out_addline_infile(out, m->line_no);
1824 if(m->scope==PRIVATE_SCOPE)
1825 print_method(out, "static ", "\n", "", " ", "", "\n",
1826 m, FALSE, FALSE, TRUE);
1827 else /* PUBLIC, PROTECTED */
1828 print_method(out, "", "\n", "", " ", "", "\n",
1829 m, FALSE, FALSE, TRUE);
1830 out_addline_outfile(out);
1831 out_printf(out, "{\n"
1832 "\t%sClass *klass;\n", typebase);
1833 print_preconditions(m);
1834 out_printf(out, "\tklass = %s_GET_CLASS(%s);\n\n"
1835 "\tif(klass->%s)\n",
1836 macrobase, ((FuncArg *)m->args->data)->name,
1837 get_real_id(m->id));
1838 if(strcmp(m->mtype->name, "void") == 0 &&
1839 m->mtype->pointer == NULL) {
1841 out_printf(out, "\t\t(*klass->%s)(%s",
1843 ((FuncArg *)m->args->data)->name);
1844 for(li=m->args->next;li;li=g_list_next(li)) {
1845 FuncArg *fa = li->data;
1846 out_printf(out, ",%s", fa->name);
1848 out_printf(out, ");\n}\n");
1851 out_printf(out, "\t\treturn (*klass->%s)(%s",
1853 ((FuncArg *)m->args->data)->name);
1854 for(li=m->args->next;li;li=g_list_next(li)) {
1855 FuncArg *fa = li->data;
1856 out_printf(out, ",%s", fa->name);
1858 out_printf(out, ");\n"
1861 print_type(out, m->mtype, TRUE);
1863 out_printf(out, ")(%s);\n}\n", m->defreturn);
1865 out_printf(out, ")(%s);\n}\n", m->onerror);
1867 out_printf(out, ")(0);\n}\n");
1873 out_addline_infile(out, m->line_no);
1874 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
1875 m, FALSE, FALSE, TRUE);
1876 print_method_body(m, FALSE);
1877 /* the outfile line was added above */
1879 case OVERRIDE_METHOD:
1883 out_addline_infile(out, m->line_no);
1884 s = g_strdup_printf("\n___%x_", (guint)m->unique_id);
1885 print_method(out, "static ", s, "", " ", "", "\n",
1886 m, FALSE, FALSE, FALSE);
1888 out_addline_outfile(out);
1889 s = replace_sep(m->otype, '_');
1891 args = get_arg_names_for_macro(m);
1893 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
1894 "\t{ if(%s_CLASS(parent_class)->%s) \\\n"
1895 "\t\t(* %s_CLASS(parent_class)->%s)(%s); }\n",
1896 args, s, get_real_id(m->id), s, get_real_id(m->id), args);
1898 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
1899 "\t((%s_CLASS(parent_class)->%s)? \\\n"
1900 "\t\t(* %s_CLASS(parent_class)->%s)(%s): \\\n"
1902 args, s, get_real_id(m->id), s, get_real_id(m->id), args);
1903 out_printf(out, "(");
1904 print_type(out, m->mtype, TRUE);
1905 out_printf(out, ")%s))\n",
1906 m->onerror?m->onerror:"0");
1910 print_method_body(m, TRUE);
1911 /* the outfile line was added above */
1912 out_printf(out, "#undef PARENT_HANDLER\n");
1922 char *outfile, *outfileh, *outfileph;
1925 outfile = g_strconcat(filebase, ".c", NULL);
1927 outfile = g_strconcat(filebase, ".cc", NULL);
1928 if(no_touch_headers)
1929 outfileh = g_strconcat("#gob#", filebase, ".h#gob#", NULL);
1931 outfileh = g_strconcat(filebase, ".h", NULL);
1933 if((privates > 0 || protecteds > 0 ||
1934 private_header == PRIVATE_HEADER_ALWAYS) &&
1935 private_header != PRIVATE_HEADER_NEVER)
1936 outfileph = g_strconcat(filebase, "-private.h", NULL);
1942 devnull = fopen("/dev/null", "w");
1944 g_error("Cannot open null device");
1950 out = fopen(outfile, "w");
1952 g_error("Cannot open outfile: %s", outfile);
1954 outh = fopen(outfileh, "w");
1956 g_error("Cannot open outfile: %s", outfileh);
1958 outph = fopen(outfileph, "w");
1960 g_error("Cannot open outfile: %s", outfileh);
1966 put_argument_nongnu_wrappers(Class *c)
1970 if(get_arguments < 0 && set_arguments < 0)
1973 for(li=c->nodes;li;li=g_list_next(li)) {
1975 Argument *a = (Argument *)n;
1979 if(n->type != ARGUMENT_NODE)
1982 aname = g_strdup(a->name);
1986 cast = get_type(a->atype, TRUE);
1988 cast = g_strdup(get_cast(a->gtktype, TRUE));
1992 out_printf(outh, "#define %s_ARG_%s(arg) \t"
1993 "\"%s\",(%s)(arg)\n",
1994 macrobase, aname, a->name, cast);
1996 out_printf(outh, "#define %s_GET_ARG_%s(arg)\t"
1997 "\"%s\",(%s*)(arg)\n",
1998 macrobase, aname, a->name, cast);
2001 out_printf(outh, "#define %s_ARG_%s(arg) \t"
2003 macrobase, aname, a->name);
2005 out_printf(outh, "#define %s_GET_ARG_%s(arg)\t"
2007 macrobase, aname, a->name);
2015 put_argument_gnu_wrappers(Class *c)
2019 if(get_arguments < 0 && set_arguments < 0)
2022 for(li=c->nodes;li;li=g_list_next(li)) {
2024 Argument *a = (Argument *)n;
2027 if(n->type != ARGUMENT_NODE)
2029 s = g_strdup(a->name);
2032 cast = get_type(a->atype, TRUE);
2034 cast = g_strdup(get_cast(a->gtktype, TRUE));
2037 out_printf(outh, "#define %s_ARG_%s(arg) \t"
2038 "\"%s\",({%sz = (arg); z;})\n",
2039 macrobase, s, a->name, cast);
2041 out_printf(outh, "#define %s_GET_ARG_%s(arg)\t"
2042 "\"%s\",({%s*z = (arg); z;})\n",
2043 macrobase, s, a->name, cast);
2046 out_printf(outh, "#define %s_ARG_%s(arg) \t"
2048 macrobase, s, a->name);
2050 out_printf(outh, "#define %s_GET_ARG_%s(arg)\t"
2052 macrobase, s, a->name);
2060 print_ccode_block(CCode *cc)
2063 switch(cc->cctype) {
2065 /* HT code is printed exactly like normal header
2066 code but is printed before */
2069 out_printf(fp, "\n");
2072 /* AT code is printed exactly like normal 'all'
2073 code but is printed before */
2076 out_printf(outph, "\n");
2077 out_printf(outph, "%s\n", cc->cbuf);
2078 out_addline_infile(outph, cc->line_no);
2079 out_addline_outfile(outph);
2081 out_printf(outh, "\n");
2082 out_printf(outh, "%s\n", cc->cbuf);
2084 out_printf(fp, "\n");
2085 out_addline_infile(fp, cc->line_no);
2090 out_printf(fp, "\n");
2091 out_addline_infile(fp, cc->line_no);
2098 out_printf(fp, "\n");
2099 out_addline_infile(fp, cc->line_no);
2102 out_printf(fp, "%s\n", cc->cbuf);
2103 if(cc->cctype == C_CCODE ||
2104 cc->cctype == A_CCODE ||
2105 cc->cctype == AT_CCODE ||
2106 cc->cctype == PH_CCODE)
2107 out_addline_outfile(fp);
2111 print_class_block(Class *c)
2115 gboolean printed_private = FALSE;
2118 out_printf(out, "/* utility types we may need */\n");
2119 if(special_array[SPECIAL_2POINTER])
2120 out_printf(out, "typedef struct { "
2121 "gpointer a; gpointer b; "
2122 "} ___twopointertype;\n");
2123 if(special_array[SPECIAL_3POINTER])
2124 out_printf(out, "typedef struct { "
2125 "gpointer a; gpointer b; "
2127 "} ___threepointertype;\n");
2128 if(special_array[SPECIAL_INT_POINTER])
2129 out_printf(out, "typedef struct { "
2130 "gint a; gpointer b; "
2131 "} ___intpointertype;\n");
2132 out_printf(out, "\n");
2135 out_printf(outh, "\n/*\n"
2136 " * Type checking and casting macros\n"
2138 out_printf(outh, "#define %s\t"
2139 "(%s_get_type())\n",
2140 macrotype, funcbase);
2141 out_printf(outh, "#define %s(obj)\t"
2142 "GTK_CHECK_CAST((obj), %s_get_type(), %s)\n",
2143 macrobase, funcbase, typebase);
2144 out_printf(outh, "#define %s_CONST(obj)\t"
2145 "GTK_CHECK_CAST((obj), %s_get_type(), %s const)\n",
2146 macrobase, funcbase, typebase);
2147 out_printf(outh, "#define %s_CLASS(klass)\t"
2148 "GTK_CHECK_CLASS_CAST((klass), %s_get_type(), %sClass)\n",
2149 macrobase, funcbase, typebase);
2150 out_printf(outh, "#define %s(obj)\t"
2151 "GTK_CHECK_TYPE((obj), %s_get_type ())\n\n",
2153 out_printf(outh, "#ifdef GTK_CHECK_GET_CLASS\n"
2154 "#define %s_GET_CLASS(obj)\t"
2155 "GTK_CHECK_GET_CLASS((obj), %s_get_type(), %sClass)\n",
2156 macrobase, funcbase, typebase);
2157 out_printf(outh, "#else /* !GTK_CHECK_GET_CLASS */\n"
2158 "#define %s_GET_CLASS(obj)\t"
2159 "((%sClass *)GTK_OBJECT(obj)->klass)\n"
2160 "#endif /* GTK_CHECK_GET_CLASS */\n",
2161 macrobase, typebase);
2163 if( ! no_self_alias) {
2164 out_printf(out, "/* self casting macros */\n");
2165 out_printf(out, "#define SELF(x) %s(x)\n", macrobase);
2166 out_printf(out, "#define SELF_CONST(x) %s_CONST(x)\n", macrobase);
2167 out_printf(out, "#define IS_SELF(x) %s(x)\n", macrois);
2168 out_printf(out, "#define SELF_CLASS(x) %s_CLASS(x)\n\n",
2170 out_printf(out, "#define SELF_GET_CLASS(x) %s_GET_CLASS(x)\n\n",
2173 out_printf(out, "/* self typedefs */\n");
2174 out_printf(out, "typedef %s Self;\n", typebase);
2175 out_printf(out, "typedef %sClass SelfClass;\n\n", typebase);
2178 out_printf(out, "/* GTK_CLASS_TYPE for 1.2<->1.3/2.0 GTK+ compatibility */\n");
2180 "#ifndef GTK_CLASS_TYPE\n"
2181 "#define GTK_CLASS_TYPE(x) (GTK_OBJECT_CLASS(x)->type)\n"
2182 "#endif /* GTK_CLASS_TYPE */\n\n");
2184 if(privates > 0 || always_private_struct) {
2185 out_printf(outh, "\n/* Private structure type */\n");
2186 out_printf(outh, "typedef struct _%sPrivate %sPrivate;\n",
2187 typebase, typebase);
2189 out_printf(outh, "/* There are no privates, this "
2190 "structure is thus never defined */\n");
2193 out_printf(outh, "\n/*\n"
2194 " * Main object structure\n"
2196 s = replace_sep(c->otype, '_');
2198 out_printf(outh, "#ifndef __TYPEDEF_%s__\n"
2199 "#define __TYPEDEF_%s__\n", s, s);
2201 out_printf(outh, "typedef struct _%s %s;\n"
2202 "#endif\n", typebase, typebase);
2203 out_printf(outh, "struct _%s {\n\t%s __parent__;\n",
2204 typebase, ptypebase);
2205 for(l=c->nodes; l; l=g_list_next(l)) {
2206 static gboolean printed_public = FALSE;
2208 Variable *v = (Variable *)n;
2209 if(n->type == VARIABLE_NODE &&
2210 v->scope == PUBLIC_SCOPE) {
2211 if( ! printed_public) {
2212 out_printf(outh, "\t/*< public >*/\n");
2213 printed_public = TRUE;
2215 put_variable((Variable *)n, outh);
2218 /* put protecteds always AFTER publics */
2219 for(l=c->nodes; l; l=g_list_next(l)) {
2221 Variable *v = (Variable *)n;
2222 if(n->type == VARIABLE_NODE &&
2223 v->scope == PROTECTED_SCOPE) {
2224 if( ! printed_private) {
2225 out_printf(outh, "\t/*< private >*/\n");
2226 printed_private = TRUE;
2228 put_variable((Variable *)n, outh);
2231 if(privates > 0 || always_private_struct) {
2232 if( ! printed_private)
2233 out_printf(outh, "\t/*< private >*/\n");
2234 out_printf(outh, "\t%sPrivate *_priv;\n", typebase);
2236 out_printf(outh, "};\n");
2241 /* if we are to stick this into the private
2242 header, if not stick it directly into the
2249 out_printf(outfp, "struct _%sPrivate {\n",
2251 for(l=c->nodes; l; l=l->next) {
2253 Variable *v = (Variable *)n;
2254 if(n->type == VARIABLE_NODE &&
2255 v->scope == PRIVATE_SCOPE) {
2256 out_addline_infile(outfp, v->line_no);
2257 put_variable(v, outfp);
2260 out_addline_outfile(outfp);
2261 out_printf(outfp, "};\n");
2264 out_printf(outh, "\n/*\n"
2265 " * Class definition\n"
2267 out_printf(outh, "typedef struct _%sClass %sClass;\n",
2268 typebase, typebase);
2270 "struct _%sClass {\n\t%sClass __parent__;\n",
2271 typebase, ptypebase);
2272 for(l = c->nodes; l != NULL; l = l->next) {
2274 if(n->type == METHOD_NODE)
2275 put_vs_method((Method *)n);
2277 /* put class scope variables */
2278 for(l = c->nodes; l != NULL; l = l->next) {
2280 Variable *v = (Variable *)n;
2281 if(n->type == VARIABLE_NODE &&
2282 v->scope == CLASS_SCOPE)
2283 put_variable((Variable *)n, outh);
2285 out_printf(outh, "};\n\n");
2287 out_printf(out, "/* here are local prototypes */\n");
2288 if(set_arguments > 0) {
2289 out_printf(out, "static void ___object_set_arg "
2290 "(GtkObject *object, GtkArg *arg, "
2291 "guint arg_id);\n");
2293 if(get_arguments > 0) {
2294 out_printf(out, "static void ___object_get_arg "
2295 "(GtkObject *object, GtkArg *arg, "
2296 "guint arg_id);\n");
2299 out_printf(outh, "\n/*\n"
2300 " * Public methods\n"
2303 out_printf(outh, "GtkType\t%s_get_type\t(void)", funcbase);
2305 out_printf(outh, " G_GNUC_CONST;\n");
2307 out_printf(outh, ";\n");
2310 for(l = c->nodes; l != NULL; l = l->next) {
2312 if(n->type == METHOD_NODE) {
2313 put_pub_method((Method *)n);
2314 put_prot_method((Method *)n);
2315 put_priv_method_prot((Method *)n);
2319 /* this idea is less and less apealing to me */
2321 out_printf (outh, "\n/*\n"
2322 " * Signal connection wrapper macros\n"
2325 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
2326 put_signal_macros (c, TRUE);
2327 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
2328 put_signal_macros (c, FALSE);
2329 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n");
2331 put_signal_macros (c, FALSE);
2335 /* argument wrapping macros */
2336 if(get_arguments > 0 || set_arguments > 0) {
2337 out_printf(outh, "\n/*\n"
2338 " * Argument wrapping macros\n"
2341 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
2342 put_argument_gnu_wrappers(c);
2343 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
2344 put_argument_nongnu_wrappers(c);
2345 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n");
2347 put_argument_nongnu_wrappers(c);
2352 for(l = c->nodes; l != NULL; l = l->next) {
2354 if(n->type == METHOD_NODE)
2355 add_signal_prots((Method *)n);
2363 if(any_method_to_alias(c)) {
2365 out_printf(out, "/* Short form macros */\n");
2366 out_printf(out, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
2367 make_method_gnu_aliases(c);
2368 out_printf(out, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n");
2370 make_method_nongnu_aliases(c);
2373 out_printf(out, "/* a macro for creating a new object of our type */\n");
2375 "#define GET_NEW ((%s *)gtk_type_new(%s_get_type()))\n\n",
2376 typebase, funcbase);
2386 if(set_arguments > 0) {
2387 add_getset_arg(c, TRUE);
2390 if(get_arguments > 0) {
2391 add_getset_arg(c, FALSE);
2394 for(l = c->nodes; l != NULL; l = l->next) {
2396 if(n->type == METHOD_NODE)
2397 put_method((Method *)n);
2400 add_bad_hack_to_avoid_unused_warnings(c);
2404 print_version_macros(void)
2406 int major=0, minor=0, pl=0;
2407 sscanf(VERSION, "%d.%d.%d", &major, &minor, &pl);
2409 out_printf(out, "#define GOB_VERSION_MAJOR %d\n", major);
2410 out_printf(out, "#define GOB_VERSION_MINOR %d\n", minor);
2411 out_printf(out, "#define GOB_VERSION_PATCHLEVEL %d\n\n", pl);
2415 print_file_comments(void)
2419 out_printf(outh, "/* Generated by GOB (v%s)"
2420 " (do not edit directly) */\n\n", VERSION);
2422 out_printf(outph, "/* Generated by GOB (v%s)"
2423 " (do not edit directly) */\n\n", VERSION);
2424 out_printf(out, "/* Generated by GOB (v%s) on %s"
2425 " (do not edit directly) */\n\n",
2426 VERSION, ctime(&curtime));
2428 out_printf(out, "/* End world hunger, donate to the World Food Programme, http://www.wfp.org */\n\n");
2432 print_includes(void)
2434 gboolean found_header;
2437 /* We may need string.h for memset */
2438 if(destructors > 0 &&
2439 ! g_list_find_custom(include_files, "string.h", (GCompareFunc)strcmp)) {
2440 out_printf(out, "#include <string.h> /* memset() */\n\n");
2443 p = g_strconcat(filebase, ".h", NULL);
2444 found_header = TRUE;
2445 if( ! g_list_find_custom(include_files, p, (GCompareFunc)strcmp)) {
2446 out_printf(out, "#include \"%s.h\"\n\n", filebase);
2447 found_header = FALSE;
2451 /* if we are creating a private header see if it was included */
2453 p = g_strconcat(filebase, "-private.h", NULL);
2454 if( ! g_list_find_custom(include_files, p,
2455 (GCompareFunc)strcmp)) {
2456 out_printf(out, "#include \"%s-private.h\"\n\n",
2459 error_printf(GOB_WARN, 0,
2460 "Implicit private header include "
2462 "\tsource file, while public "
2463 "header is at a custom location, "
2465 "\texplicitly include "
2466 "the private header below the "
2474 print_header_prefixes(void)
2478 p = replace_sep(((Class *)class)->otype, '_');
2480 out_printf(outh, "#ifndef __%s_H__\n#define __%s_H__\n\n", p, p);
2482 out_printf(outph, "#ifndef __%s_PRIVATE_H__\n"
2483 "#define __%s_PRIVATE_H__\n\n"
2484 "#include \"%s.h\"\n\n", p, p, filebase);
2487 if( ! no_extern_c) {
2488 out_printf(outh, "#ifdef __cplusplus\n"
2490 "#endif /* __cplusplus */\n\n");
2492 out_printf(outph, "#ifdef __cplusplus\n"
2494 "#endif /* __cplusplus */\n\n");
2499 print_header_postfixes(void)
2502 out_printf(outh, "\n#ifdef __cplusplus\n"
2504 "#endif /* __cplusplus */\n");
2505 out_printf(outh, "\n#endif\n");
2508 out_printf(outph, "\n#ifdef __cplusplus\n"
2510 "#endif /* __cplusplus */\n");
2511 out_printf(outph, "\n#endif\n");
2520 /* print the AT_CCODE blocks */
2521 for(li = nodes; li != NULL; li = li->next) {
2522 Node *node = li->data;
2523 if(node->type == CCODE_NODE) {
2524 CCode *cc = (CCode *)node;
2525 if(cc->cctype == AT_CCODE)
2526 print_ccode_block((CCode *)node);
2532 print_header_top(void)
2536 /* mandatory include */
2537 out_printf(outh, "#include <gtk/gtk.h>\n\n");
2539 /* print the HT_CCODE blocks */
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 print_ccode_block((CCode *)node);
2551 generate_outfiles(void)
2555 print_file_comments();
2561 print_header_prefixes();
2563 print_version_macros();
2567 for(li=nodes;li;li=g_list_next(li)) {
2568 Node *node = li->data;
2569 if(node->type == CCODE_NODE) {
2570 CCode *cc = (CCode *)node;
2571 if(cc->cctype != HT_CCODE &&
2572 cc->cctype != AT_CCODE)
2573 print_ccode_block((CCode *)node);
2574 } else if(node->type == CLASS_NODE) {
2575 print_class_block((Class *)node);
2577 g_assert_not_reached();
2580 print_header_postfixes();
2586 fprintf(stderr, "Gob version %s\n\n", VERSION);
2587 fprintf(stderr, "gob [options] file.gob\n\n");
2588 fprintf(stderr, "Options:\n"
2589 "\t--help,-h,-? Display this help\n"
2590 "\t--version Display version\n"
2591 "\t--exit-on-warn,-w Exit with an error on warnings\n"
2592 "\t--no-exit-on-warn Don't exit on warnings [default]\n"
2593 "\t--for-cpp Create C++ files\n"
2594 "\t--no-extern-c Never print extern \"C\" into the "
2596 "\t--no-gnu Never use GNU extentions\n"
2597 "\t--no-touch-headers Don't touch headers unless they "
2599 "\t--always-private-header Always create a private header "
2601 "\t even if it would be empty "
2603 "\t--ondemand-private-header Create private header only when "
2605 "\t--no-private-header Don't create a private header, "
2607 "\t structure and protected "
2608 "prototypes inside c file\n"
2609 "\t--always-private-struct Always create a private pointer "
2611 "\t the object structure\n"
2612 "\t--no-write,-n Don't write output files, just "
2614 "\t--no-lines Don't print '#line' to output\n"
2615 "\t--no-self-alias Don't create self type and macro "
2617 "\t--no-kill-underscores Don't remove the leading underscore "
2619 "\t short id names\n");
2623 parse_options(int argc, char *argv[])
2626 int got_file = FALSE;
2627 int no_opts = FALSE;
2631 for(i = 1 ; i < argc; i++) {
2633 argv[i][0] != '-') {
2636 fprintf(stderr, "Specify only one file!\n");
2642 } else if(strcmp(argv[i], "--help")==0) {
2645 } else if(strcmp(argv[i], "--version")==0) {
2646 fprintf(stderr, "Gob version %s\n", VERSION);
2648 } else if(strcmp(argv[i], "--exit-on-warn")==0) {
2649 exit_on_warn = TRUE;
2650 } else if(strcmp(argv[i], "--no-exit-on-warn")==0) {
2651 exit_on_warn = FALSE;
2652 } else if(strcmp(argv[i], "--for-cpp")==0) {
2654 } else if(strcmp(argv[i], "--no-touch-headers")==0) {
2655 no_touch_headers = TRUE;
2656 } else if(strcmp(argv[i], "--ondemand-private-header")==0) {
2657 private_header = PRIVATE_HEADER_ONDEMAND;
2658 } else if(strcmp(argv[i], "--always-private-header")==0) {
2659 private_header = PRIVATE_HEADER_ALWAYS;
2660 } else if(strcmp(argv[i], "--no-private-header")==0) {
2661 private_header = PRIVATE_HEADER_NEVER;
2662 } else if(strcmp(argv[i], "--no-gnu")==0) {
2664 } else if(strcmp(argv[i], "--no-extern-c")==0) {
2666 } else if(strcmp(argv[i], "--no-write")==0) {
2668 } else if(strcmp(argv[i], "--no-lines")==0) {
2670 } else if(strcmp(argv[i], "--no-self-alias")==0) {
2671 no_self_alias = TRUE;
2672 } else if(strcmp(argv[i], "--no-kill-underscores")==0) {
2673 no_kill_underscores = TRUE;
2674 } else if(strcmp(argv[i], "--always-private-struct")==0) {
2675 always_private_struct = TRUE;
2676 } else if(strcmp(argv[i], "--")==0) {
2677 /*further arguments are files*/
2679 } else if(strncmp(argv[i], "--", 2)==0) {
2680 /*unknown long option*/
2681 fprintf(stderr, "Unknown option '%s'!\n", argv[i]);
2685 /*by now we know we have a string starting with
2686 - which is a short option string*/
2688 for(p = argv[i] + 1; *p; p++) {
2702 "Unknown option '%c'!\n", *p);
2711 /* this is a somewhat ugly hack, but it appears to work */
2713 compare_and_move_header(void)
2715 char *hfnew = g_strconcat("#gob#", filebase, ".h#gob#", NULL);
2716 char *hf = g_strconcat(filebase, ".h", NULL);
2718 if(stat(hf, &s) == 0) {
2720 s = g_strdup_printf("cmp '%s' '%s' > /dev/null", hf, hfnew);
2721 if(system(s) == 0) {
2722 if(unlink(hfnew) != 0)
2723 error_printf(GOB_ERROR, 0,
2724 "Can't remove new header file");
2732 error_printf(GOB_ERROR, 0,
2733 "Can't remove old header file");
2735 if(rename(hfnew, hf) != 0)
2736 error_printf(GOB_ERROR, 0,
2737 "Can't rename new header file");
2743 main(int argc, char *argv[])
2745 parse_options(argc, argv);
2748 yyin = fopen(filename, "r");
2750 fprintf(stderr, "Error: can't open file '%s'\n",
2757 /* This is where parsing is done */
2760 g_error("Parsing errors, quitting");
2763 error_print(GOB_ERROR, 0, " no class defined");
2766 exit_on_error = FALSE;
2768 signals = count_signals((Class *)class);
2769 set_arguments = count_set_arguments((Class *)class);
2770 get_arguments = count_get_arguments((Class *)class);
2771 overrides = count_overrides((Class *)class);
2772 privates = count_privates((Class *)class);
2773 protecteds = count_protecteds((Class *)class);
2774 destructors = count_destructors((Class *)class);
2775 initializers = count_initializers((Class *)class);
2778 make_inits((Class *)class);
2779 if(destructors > 0) {
2780 need_destroy = TRUE;
2781 find_destroy((Class *)class);
2784 need_finalize = TRUE;
2785 find_finalize((Class *)class);
2787 check_bad_symbols((Class *)class);
2788 check_duplicate_symbols((Class *)class);
2789 check_duplicate_overrides((Class *)class);
2790 check_duplicate_signals_args((Class *)class);
2791 check_public_new((Class *)class);
2792 check_vararg((Class *)class);
2793 check_firstarg((Class *)class);
2794 check_nonvoidempty((Class *)class);
2795 check_signal_args((Class *)class);
2796 check_argument_types((Class *)class);
2797 check_func_arg_checks((Class *)class);
2799 exit_on_error = TRUE;
2804 any_special = setup_special_array((Class *)class, special_array);
2808 generate_outfiles();
2819 if(no_touch_headers &&
2821 compare_and_move_header();