2 * Copyright (C) 1999 the Free Software Foundation.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
39 char *filename = NULL;
48 extern GList *include_files;
50 extern GHashTable *gtk_doc_hash;
53 static char *funcbase;
54 static char *pfuncbase;
55 static char *macrobase;
57 static char *macrotype;
58 static char *typebase;
59 static char *ptypebase;
61 static int signals = 0; /* number of signals */
62 static int arguments = 0; /* number of named arguments */
63 static int overrides = 0; /* number of override methods */
64 static int privates = 0; /* number of private data members */
65 static int protecteds = 0; /* number of protected methods */
66 static int destructors = 0; /* number of variable destructors */
67 static int initializers = 0; /* number of variable initializers */
69 static gboolean made_aliases = FALSE; /* if we made any shorthand aliases
70 and need the REALLY UGLY HACK to
78 gboolean no_touch_headers = FALSE;
79 gboolean for_cpp = FALSE;
80 gboolean no_gnu = FALSE;
81 gboolean exit_on_warn = FALSE;
82 gboolean exit_on_error = TRUE;
83 gboolean got_error = FALSE;
84 gboolean always_private_header = FALSE;
85 gboolean no_private_header = FALSE;
86 gboolean no_extern_c = FALSE;
87 gboolean no_write = FALSE;
88 gboolean no_lines = FALSE;
93 filebase = replace_sep(((Class *)class)->otype, '-');
96 funcbase = replace_sep(((Class *)class)->otype, '_');
99 pfuncbase = replace_sep(((Class *)class)->ptype, '_');
100 g_strdown(pfuncbase);
102 macrobase = replace_sep(((Class *)class)->otype, '_');
105 macrois = make_pre_macro(((Class *)class)->otype, "IS");
106 macrotype = make_pre_macro(((Class *)class)->otype, "TYPE");
108 typebase = remove_sep(((Class *)class)->otype);
110 ptypebase = remove_sep(((Class *)class)->ptype);
114 get_type(Type *t, gboolean postfix_to_stars)
121 s = remove_sep(t->name);
122 gs = g_string_new(s);
127 if(postfix_to_stars) {
129 /*XXX: this is ugly perhaps we can do this whole postfix thing
130 in a nicer way, we just count the number of '[' s and from
131 that we deduce the number of dimensions, so that we can print
133 for(p=t->postfix; p && *p; p++)
134 if(*p == '[') extra++;
136 g_string_append_c(gs,' ');
138 for(i=0; i<(t->stars+extra); i++)
139 g_string_append_c(gs, '*');
142 g_string_free(gs, FALSE);
147 get_gtk_doc(char *id)
154 val = g_hash_table_lookup(gtk_doc_hash, id);
156 return g_strdup_printf("/**\n * %s_%s:\n%s **/\n",
158 s = g_strconcat(funcbase, "_", id, NULL);
159 val = g_hash_table_lookup(gtk_doc_hash, s);
162 return g_strdup_printf("/**\n * %s_%s:\n%s **/\n",
168 print_type(FILE *fp, Type *t, gboolean postfix_to_stars)
172 s = get_type(t, postfix_to_stars);
173 out_printf(fp, "%s", s);
179 print_method(FILE *fp, char *typeprefix, char *nameprefix,
181 char *namepostfix, char *postfix, Method *m,
182 gboolean one_arg_per_line,
183 gboolean no_funcbase)
187 out_printf(fp, "%s", typeprefix);
188 print_type(fp, m->mtype, TRUE);
190 out_printf(fp, "%s%s%s%s(",
191 nameprefix, subnameprefix, m->id, namepostfix);
193 out_printf(fp,"%s%s_%s%s%s(",
194 nameprefix, funcbase, subnameprefix, m->id,
198 for(li=m->args; li; li=g_list_next(li)) {
199 FuncArg *arg = li->data;
200 print_type(fp, arg->atype, FALSE);
202 out_printf(fp, "%s%s,%s", arg->name,
204 arg->atype->postfix:"",
205 one_arg_per_line?"\n\t\t\t\t\t":" ");
207 out_printf(fp, "%s%s", arg->name,
209 arg->atype->postfix:"");
212 out_printf(fp, ",%s...",
213 one_arg_per_line?"\n\t\t\t\t\t":" ");
215 out_printf(fp, "void");
217 out_printf(fp, ")%s", postfix);
221 any_method_to_alias(Class *c)
225 for(li=c->nodes;li;li=g_list_next(li)) {
226 Node *node = li->data;
227 if(node->type == METHOD_NODE) {
228 Method *m = (Method *)node;
230 if(m->method == INIT_METHOD ||
231 m->method == CLASS_INIT_METHOD ||
232 m->method == OVERRIDE_METHOD)
243 make_method_gnu_aliases(Class *c)
247 for(li=c->nodes;li;li=g_list_next(li)) {
248 Node *node = li->data;
249 if(node->type == METHOD_NODE) {
250 Method *m = (Method *)node;
252 if(m->method == INIT_METHOD ||
253 m->method == CLASS_INIT_METHOD ||
254 m->method == OVERRIDE_METHOD)
257 /* in C++ mode don't alias new */
258 if(for_cpp && strcmp(m->id, "new")==0)
261 out_printf(out, "static const typeof(&%s_%s) %s "
262 "__attribute__ ((__unused__)) "
263 "= %s_%s;\n", funcbase, m->id, m->id,
265 out_printf(out, "#define %s(args...) "
266 "%s_%s(##args)\n", m->id, funcbase, m->id);
272 make_method_nongnu_aliases(Class *c)
276 for(li=c->nodes; li; li=g_list_next(li)) {
277 Node *node = li->data;
278 if(node->type == METHOD_NODE) {
279 Method *m = (Method *)node;
281 if(m->method == INIT_METHOD ||
282 m->method == CLASS_INIT_METHOD ||
283 m->method == OVERRIDE_METHOD)
286 /* in C++ mode don't alias new */
287 if(for_cpp && strcmp(m->id, "new")==0)
290 print_method(out, "static ", "(* ", "", ") ", "",
292 out_printf(out, " = %s_%s;\n", funcbase, m->id);
300 add_bad_hack_to_avoid_unused_warnings(Class *c)
304 /* if we haven't had any methods, just return */
309 out_printf(out,"\n\n#ifndef __GNUC__\n");
311 "/*REALLY BAD HACK\n"
312 " This is to avoid unused warnings if you don't call\n"
313 " some method. I need to find a better way to do\n"
314 " this, not needed in GCC since we use some gcc\n"
315 " extentions to make saner, faster code */\n"
317 "___%s_really_bad_hack_to_avoid_warnings(void)\n"
319 for(li=c->nodes;li;li=g_list_next(li)) {
320 Node *node = li->data;
321 if(node->type == METHOD_NODE) {
322 Method *m = (Method *)node;
324 if(m->method == INIT_METHOD ||
325 m->method == CLASS_INIT_METHOD ||
326 m->method == OVERRIDE_METHOD)
329 /* in C++ mode we don't alias new */
330 if(for_cpp && strcmp(m->id,"new")==0)
333 out_printf(out,"\t((void (*)(void))%s)();\n",m->id);
336 out_printf(out, "\t___%s_really_bad_hack_to_avoid_warnings();\n",
339 out_printf(out,"}\n#endif /* __GNUC__ */\n\n");
341 out_printf(out,"}\n\n");
345 put_variable(Variable *v, FILE *fp)
348 print_type(fp,v->vtype,FALSE);
349 out_printf(fp,"%s%s;",v->id,
351 v->vtype->postfix:"");
352 if(v->scope == PROTECTED_SCOPE)
353 out_printf(fp," /* protected */");
358 put_vs_method(Method *m)
360 if(m->method != SIGNAL_LAST_METHOD &&
361 m->method != SIGNAL_FIRST_METHOD &&
362 m->method != VIRTUAL_METHOD)
365 /* if a signal mark it as such */
366 if(m->method != VIRTUAL_METHOD)
367 print_method(outh,"\t/*signal*/","(* ","",") ",";\n",m,
370 print_method(outh,"\t","(* ","",") ",";\n",m,FALSE,TRUE);
374 put_pub_method(Method *m)
376 if(m->scope != PUBLIC_SCOPE)
379 print_method(outh,"","\t","","\t",";\n",m,TRUE,FALSE);
382 /* I'm starting not to like this idea */
385 put_signal_connect(Method *m)
387 if(m->method != SIGNAL_LAST_METHOD &&
388 m->method != SIGNAL_FIRST_METHOD)
391 out_printf(outh, "guint \t%s_%s__connect_full\t(%s *object,\n"
392 "\t\t\t\t\tconst char *name,\n"
393 "\t\t\t\t\tGtkSignalFunc func,\n"
394 "\t\t\t\t\tGtkCallbackMarshal marshal,\n"
395 "\t\t\t\t\tgpointer data,\n"
396 "\t\t\t\t\tGtkDestroyNotify destroy_func,\n"
397 "\t\t\t\t\tgboolean object_signal,\n"
398 "\t\t\t\t\tgboolean after);\n",
399 funcbase, m->id, typebase);
401 out_printf(outh, "#define %s_%s__connect(object,name,func,data) "
402 "%s_%s__connect_full((object),(name),(func),NULL,"
403 "(data),NULL,FALSE,FALSE)\n",
404 funcbase, m->id, funcbase, m->id);
405 out_printf(outh, "#define %s_%s__connect_after(object,name,func,data) "
406 "%s__connect_%s_full((object),(name),(func),NULL,"
407 "(data),NULL,FALSE,TRUE)\n",
408 funcbase, m->id, funcbase, m->id);
410 out_printf(outh, "guint \t%s_%s__connect_while_alive\t(%s *object,\n"
411 "\t\t\t\t\tconst char *name,\n"
412 "\t\t\t\t\tGtkSignalFunc func,\n"
413 "\t\t\t\t\tgpointer data,\n"
414 "\t\t\t\t\tGtkObject *alive_object);\n\n",
415 funcbase, m->id, typebase);
421 put_prot_method(Method *m)
423 if(m->scope != PROTECTED_SCOPE)
427 print_method(outph,"","\t","","\t",";\n",m,FALSE,FALSE);
429 print_method(out,"","\t","","\t",";\n",m,FALSE,FALSE);
433 put_priv_method_prot(Method *m)
435 if(m->method == SIGNAL_LAST_METHOD ||
436 m->method == SIGNAL_FIRST_METHOD ||
437 m->method == VIRTUAL_METHOD) {
440 "static ", "___real_", "", " ", ";\n",
444 if(m->scope == PRIVATE_SCOPE ||
445 m->method == INIT_METHOD ||
446 m->method == CLASS_INIT_METHOD ||
447 (m->method == OVERRIDE_METHOD &&
449 print_method(out, "static ", "", "", " ",
450 no_gnu?";\n":" G_GNUC_UNUSED;\n",
455 make_func_arg(char *typename, int is_class, char *name)
462 tn = g_strconcat(typename,":Class",NULL);
464 tn = g_strdup(typename);
466 type = new_type(1,tn,NULL);
467 node = new_funcarg((Type *)type,name,NULL);
468 return g_list_prepend(NULL, node);
472 make_inits(Class *cl)
474 int got_class_init = FALSE;
475 int got_init = FALSE;
478 for(li=cl->nodes;li;li=g_list_next(li)) {
480 if(n->type == METHOD_NODE) {
481 Method *m = (Method *)n;
482 if(m->method == INIT_METHOD) {
484 print_error(FALSE,"init defined more then once",m->line_no);
486 } else if(m->method == CLASS_INIT_METHOD) {
488 print_error(FALSE,"class_init defined more then once",m->line_no);
489 got_class_init = TRUE;
493 if(!got_class_init) {
494 node = new_method(NO_SCOPE, CLASS_INIT_METHOD,
495 (Type *)new_type(0, g_strdup("void"),NULL),
496 NULL, NULL, NULL, g_strdup("class_init"),
497 make_func_arg(cl->otype, TRUE, g_strdup("c")),
498 NULL, NULL, 0, 0, FALSE);
499 cl->nodes = g_list_prepend(cl->nodes,node);
502 node = new_method(NO_SCOPE, INIT_METHOD,
503 (Type *)new_type(0, g_strdup("void"),NULL),
504 NULL, NULL, NULL, g_strdup("init"),
505 make_func_arg(cl->otype, FALSE, g_strdup("o")),
506 NULL, NULL, 0, 0, FALSE);
507 cl->nodes = g_list_prepend(cl->nodes,node);
512 make_finalize(Class *cl)
514 int got_finalize = FALSE;
517 for(li=cl->nodes;li;li=g_list_next(li)) {
519 if(n->type == METHOD_NODE) {
520 Method *m = (Method *)n;
521 if(m->method == OVERRIDE_METHOD &&
522 strcmp(m->id, "finalize")==0) {
523 if(strcmp(m->otype, "Gtk:Object")==0) {
527 print_error(FALSE,"finalize method override "
528 "of class other then Gtk:Object",
534 node = new_method(NO_SCOPE, OVERRIDE_METHOD,
535 (Type *)new_type(0,g_strdup("void"),NULL),
536 g_strdup("Gtk:Object"),
537 NULL, NULL, g_strdup("finalize"),
538 make_func_arg("Gtk:Object",FALSE,g_strdup("o")),
540 g_strdup("PARENT_HANDLER (o);\n"),
542 cl->nodes = g_list_append(cl->nodes,node);
548 /* hash of method -> name of signal prototype */
549 static GHashTable *marsh = NULL;
551 /* list of methods with different signal prototypes,
552 we check this list if we can use a signal prototype of a
553 previous signal method, there are only uniques here */
554 static GList *eq_signal_methods = NULL;
556 /* compare a list of strings */
558 is_list_equal(GList *a, GList *b)
560 for(;a && b; a=a->next, b=b->next) {
561 if(strcmp(a->data,b->data)!=0) {
565 /* the the lists were different length */
572 find_same_type_signal(Method *m)
575 for(li=eq_signal_methods;li;li=li->next) {
576 Method *mm = li->data;
577 if(is_list_equal(mm->gtktypes,m->gtktypes))
584 print_signal_marsal_args(Method *m)
586 if(strcmp(m->gtktypes->next->data,"NONE")!=0) {
589 for(i=0,li=m->gtktypes->next;li;
590 i++,li=g_list_next(li)) {
592 out_printf(out, ",\n\t\tGTK_VALUE_%s(args[%d])",
595 out_printf(out, ",\n\t\t(%s)"
596 "GTK_VALUE_%s(args[%d])",
597 get_cast(li->data,FALSE),
602 out_printf(out, ",\n\t\tfunc_data);\n}\n\n");
607 add_signal_prots(Method *m)
614 if(m->method != SIGNAL_LAST_METHOD &&
615 m->method != SIGNAL_FIRST_METHOD)
619 marsh = g_hash_table_new(NULL,NULL);
621 if(strcmp(m->gtktypes->data,"NONE")==0 &&
622 strcmp(m->gtktypes->next->data,"NONE")==0)
625 /* if we already did a signal prototype just use that */
626 mm = find_same_type_signal(m);
628 s = g_hash_table_lookup(marsh,mm);
629 g_hash_table_insert(marsh,m,s);
633 s = g_strdup_printf("Sig%d",sig++);
635 g_hash_table_insert(marsh,m,s);
636 eq_signal_methods = g_list_prepend(eq_signal_methods,m);
638 /* we know that we'll know all the gtktypes (so get_cast can't fail) */
639 out_printf(out,"\ntypedef %s (*___%s) (%s *, ",
640 get_cast(m->gtktypes->data,FALSE),s, typebase);
642 for(li=m->gtktypes->next;li;li=g_list_next(li))
643 out_printf(out,"%s, ",get_cast(li->data,FALSE));
644 out_printf(out,"gpointer);\n");
646 out_printf(out,"\nstatic void\n"
647 "___marshal_%s (GtkObject * object,\n"
648 "\tGtkSignalFunc func,\n"
649 "\tgpointer func_data,\n"
653 if(strcmp(m->gtktypes->data,"NONE")==0) {
654 out_printf(out, "\t___%s rfunc;\n\n"
655 "\trfunc = (___%s)func;\n\n"
656 "\t(*rfunc)((%s *)object",s,s,typebase);
658 out_printf(out, "\t___%s rfunc;\n\t",s);
659 print_type(out,m->mtype,TRUE);
660 out_printf(out, " *retval;\n\n"
661 "\trfunc = (___%s)func;\n\n"
662 "\tretval = GTK_RETLOC_%s(args[%d]);\n\n"
663 "\t*retval = (*rfunc)((%s *)object",
664 s,(char *)m->gtktypes->data,
665 g_list_length(m->gtktypes)-1,typebase);
667 print_signal_marsal_args(m);
675 out_printf(out,"\n");
677 out_printf(out,"enum {\n");
678 for(li=c->nodes;li;li=g_list_next(li)) {
680 if(n->type == METHOD_NODE) {
681 Method *m = (Method *)n;
682 if(m->method == SIGNAL_LAST_METHOD ||
683 m->method == SIGNAL_FIRST_METHOD) {
684 char *s = g_strdup(m->id);
686 out_printf(out,"\t%s_SIGNAL,\n",s);
691 out_printf(out,"\tLAST_SIGNAL\n};\n\n");
694 out_printf(out,"enum {\n\tARG_0");
695 for(li=c->nodes;li;li=g_list_next(li)) {
697 if(n->type == ARGUMENT_NODE) {
698 Argument *a = (Argument *)n;
699 char *s = g_strdup(a->name);
701 out_printf(out,",\n\tARG_%s",s);
705 out_printf(out, "\n};\n\n");
710 "static guint object_signals[LAST_SIGNAL] = {0};\n\n");
712 out_printf(out, "/* pointer to the class of our parent */\n");
713 out_printf(out, "static %sClass *parent_class = NULL;\n\n",ptypebase);
719 out_printf(out, "guint\n"
720 "%s_get_type (void)\n"
722 "\tstatic guint type = 0;\n\n"
724 "\t\tstatic const GtkTypeInfo info = {\n"
726 "\t\t\tsizeof (%s),\n"
727 "\t\t\tsizeof (%sClass),\n"
728 "\t\t\t(GtkClassInitFunc) %s_class_init,\n"
729 "\t\t\t(GtkObjectInitFunc) %s_init,\n"
730 "\t\t\t/* reserved_1 */ NULL,\n"
731 "\t\t\t/* reserved_2 */ NULL,\n"
732 "\t\t\t(GtkClassInitFunc) NULL,\n"
734 "\t\ttype = gtk_type_unique (%s_get_type(), &info);\n"
738 funcbase,typebase,typebase,typebase,
739 funcbase,funcbase,pfuncbase);
743 add_overrides(Class *c, char *oname, gboolean did_gtk_obj)
749 done = g_hash_table_new(g_str_hash, g_str_equal);
751 s = g_strdup("GtkObject"); /* This was already done */
752 g_hash_table_insert(done, s, s);
754 for(li=c->nodes; li; li=g_list_next(li)) {
757 Method *m = (Method *)n;
758 if(n->type != METHOD_NODE ||
759 m->method != OVERRIDE_METHOD)
762 s = remove_sep(m->otype);
764 if(g_hash_table_lookup(done,s)) {
768 g_hash_table_insert(done,s,s);
770 f = replace_sep(m->otype,'_');
773 out_printf(out,"\t%sClass *%s_class = (%sClass *)%s;\n",
778 g_hash_table_foreach(done,(GHFunc)g_free,NULL);
779 g_hash_table_destroy(done);
783 make_run_signal_flags(Method *m, gboolean last)
797 gs = g_string_new(NULL);
800 g_string_assign(gs, "GTK_RUN_LAST");
802 g_string_assign(gs, "GTK_RUN_FIRST");
804 if(m->scope == PUBLIC_SCOPE)
805 g_string_append(gs, " | GTK_RUN_ACTION");
807 for(li = m->flags; li; li = li->next) {
808 char *flag = li->data;
810 for(i=0;flags[i];i++) {
811 if(strcmp(flags[i],flag)==0)
814 /* if we haven't found it in our list */
817 s = g_strdup_printf("Unknown flag '%s' used, "
818 "perhaps it was misspelled",
820 print_error(TRUE, s, m->line_no);
823 g_string_sprintfa(gs, " | GTK_RUN_%s",flag);
828 g_string_free(gs, FALSE);
835 add_signals(Class *c)
839 out_printf(out,"\n");
840 for(li=c->nodes;li;li=g_list_next(li)) {
842 char *mar, *sig, *flags;
843 gboolean is_none, last = FALSE;
844 Method *m = (Method *)n;
846 if(n->type != METHOD_NODE ||
847 (m->method != SIGNAL_FIRST_METHOD &&
848 m->method != SIGNAL_LAST_METHOD))
851 if(m->method == SIGNAL_FIRST_METHOD)
856 if(g_hash_table_lookup(marsh, m))
857 mar = g_strconcat("___marshal_",
858 (char *)g_hash_table_lookup(marsh,m),
861 mar = g_strdup("gtk_signal_default_marshaller");
863 is_none = (strcmp(m->gtktypes->next->data, "NONE")==0);
865 sig = g_strdup(m->id);
867 flags = make_run_signal_flags(m, last);
868 out_printf(out,"\tobject_signals[%s_SIGNAL] =\n"
869 "\t\tgtk_signal_new (\"%s\",\n"
870 "\t\t\t(GtkSignalRunType)(%s),\n"
871 "\t\t\tgtk_object_class->type,\n"
872 "\t\t\tGTK_SIGNAL_OFFSET (%sClass, %s),\n"
874 "\t\t\tGTK_TYPE_%s, %d",
877 typebase,m->id,mar,(char *)m->gtktypes->data,
878 is_none?0:g_list_length(m->gtktypes->next));
885 for(l=m->gtktypes->next;l;l=g_list_next(l))
886 out_printf(out,",\n\t\t\tGTK_TYPE_%s",
890 out_printf(out,");\n");
892 out_printf(out,"\tgtk_object_class_add_signals (gtk_object_class,\n"
893 "\t\tobject_signals, LAST_SIGNAL);\n\n");
897 set_def_handlers(Class *c, char *oname)
901 out_printf(out,"\n");
902 for(li=c->nodes;li;li=g_list_next(li)) {
904 Method *m = (Method *)n;
905 if(n->type != METHOD_NODE ||
906 (m->method != SIGNAL_FIRST_METHOD &&
907 m->method != SIGNAL_LAST_METHOD &&
908 m->method != VIRTUAL_METHOD &&
909 m->method != OVERRIDE_METHOD))
913 if(m->method == OVERRIDE_METHOD) {
915 s = replace_sep(m->otype,'_');
918 out_printf(out,"\t%s_class->%s = %s_%s;\n",
919 s,m->id,funcbase,m->id);
921 out_printf(out,"\t%s_class->%s = NULL;\n",
925 out_printf(out,"\t%s->%s = ___real_%s_%s;\n",
926 oname,m->id,funcbase,m->id);
928 out_printf(out,"\t%s->%s = NULL;\n",
935 make_arguments(Class *c)
946 out_printf(out,"\n");
947 for(li=c->nodes;li;li=g_list_next(li)) {
953 if(n->type != ARGUMENT_NODE)
959 flags = g_string_new("GTK_ARG_READWRITE");
961 flags = g_string_new("GTK_ARG_READABLE");
963 flags = g_string_new("GTK_ARG_WRITABLE");
965 for(l=a->flags;l;l=g_list_next(l)) {
966 char *flag = l->data;
968 if(strcmp(flag,"READWRITE")==0 ||
969 strcmp(flag,"READABLE")==0 ||
970 strcmp(flag,"WRITABLE")==0) {
971 print_error(TRUE,"READWRITE, READABLE and "
972 "WRITABLE argument flags are "
973 "set automatically",a->line_no);
976 for(i=0;argflags[i];i++) {
977 if(strcmp(argflags[i],flag)==0)
980 /* if we haven't found it in our list */
983 s = g_strdup_printf("Unknown flag '%s' used, "
984 "perhaps it was misspelled",
986 print_error(TRUE,s,a->line_no);
989 g_string_sprintfa(flags, " | GTK_ARG_%s",flag);
992 s = g_strdup(a->name);
994 out_printf(out,"\tgtk_object_add_arg_type(\"%s::%s\",\n"
998 typebase, a->name, a->gtktype, flags->str, s);
1000 g_string_free(flags, TRUE);
1004 "\n\tgtk_object_class->set_arg = ___object_set_arg;\n"
1005 "\tgtk_object_class->get_arg = ___object_get_arg;\n");
1009 print_initializer(Method *m, Variable *v)
1013 if(v->initializer == NULL)
1016 if(v->scope == PRIVATE_SCOPE)
1017 root = g_strconcat(((FuncArg *)m->args->data)->name,
1020 root = g_strdup(((FuncArg *)m->args->data)->name);
1022 if(v->initializer_line > 0)
1023 out_addline_infile(out, v->initializer_line);
1025 out_printf(out, "\t%s->%s = %s;\n",
1026 root, v->id, v->initializer);
1028 if(v->initializer_line > 0)
1029 out_addline_outfile(out);
1038 for(li=c->nodes;li;li=g_list_next(li)) {
1041 if(n->type != METHOD_NODE)
1044 if(m->method == INIT_METHOD) {
1046 out_addline_infile(out,m->line_no);
1047 print_method(out, "static ", "\n", "", " ", "\n",
1050 out_addline_outfile(out);
1051 out_printf(out,"{\n");
1053 out_printf(out,"\t%s->_priv = "
1054 "g_new0 (%sPrivate, 1);\n",
1055 ((FuncArg *)m->args->data)->name,
1058 if(initializers > 0) {
1060 for(li = ((Class *)class)->nodes;
1064 if(n->type != VARIABLE_NODE)
1066 print_initializer(m, (Variable *)n);
1069 } else if(m->method == CLASS_INIT_METHOD) {
1071 out_addline_infile(out, m->line_no);
1072 print_method(out, "static ", "\n", "", " ", "\n",
1075 out_addline_outfile(out);
1076 out_printf(out,"{\n");
1080 "\tGtkObjectClass *"
1081 "gtk_object_class = "
1082 "(GtkObjectClass*) %s;\n",
1083 ((FuncArg *)m->args->data)->name);
1087 ((FuncArg *)m->args->data)->name,
1088 (signals>0 || arguments>0));
1090 out_printf(out,"\n\tparent_class = ");
1092 out_printf(out,"(%sClass *)",ptypebase);
1093 out_printf(out,"gtk_type_class (%s_get_type ());\n",
1099 set_def_handlers(c, ((FuncArg *)m->args->data)->name);
1108 out_printf(out," {\n");
1109 out_addline_infile(out,m->ccode_line);
1110 out_printf(out,"%s\n",m->cbuf);
1111 out_addline_outfile(out);
1112 out_printf(out," }\n");
1114 out_printf(out,"return;\n");
1116 out_printf(out,"}\n");
1121 add_getset_arg(Class *c, gboolean is_set)
1124 out_printf(out,"\nstatic void\n"
1125 "___object_%s_arg (GtkObject *object,\n"
1130 "\tself = %s (object);\n\n"
1131 "\tswitch (arg_id) {\n",
1132 is_set?"set":"get",typebase,macrobase);
1134 for(li=c->nodes;li;li=g_list_next(li)) {
1140 if(n->type != ARGUMENT_NODE)
1145 line_no = a->set_line;
1148 line_no = a->get_line;
1152 s = g_strdup(a->name);
1154 if(is_set && a->atype) {
1155 char *cast = get_type(a->atype, TRUE);
1156 out_printf(out, "\tcase ARG_%s:\n", s);
1157 if(no_gnu || for_cpp) {
1158 out_printf(out, "#define ARG "
1159 "((%s)GTK_VALUE_%s(*arg))\n",
1162 out_printf(out, "#ifdef __GNUC__\n");
1163 out_printf(out, "#define ARG "
1164 "({%s foo = GTK_VALUE_%s(*arg); "
1167 out_printf(out,"#else /* __GNUC__ */\n");
1168 out_printf(out, "#define ARG "
1169 "((%s)GTK_VALUE_%s(*arg))\n",
1171 out_printf(out,"#endif /* __GNUC__ */\n\n");
1173 out_printf(out, "\t\t{\n");
1176 out_printf(out, "\tcase ARG_%s:\n"
1177 "#define ARG (GTK_VALUE_%s(*arg))\n"
1183 out_addline_infile(out, line_no);
1184 out_printf(out,"%s\n",cbuf);
1186 out_addline_outfile(out);
1187 out_printf(out,"\t\t}\n\t\tbreak;\n"
1190 out_printf(out,"\tdefault:\n\t\tbreak;\n\t}\n}\n");
1194 print_checks(Method *m, FuncArg *fa)
1198 gboolean checked_null = FALSE;
1199 is_void = (strcmp(m->mtype->name,"void")==0 &&
1200 m->mtype->stars == 0);
1202 for(li=fa->checks;li;li=g_list_next(li)) {
1203 Check *ch = li->data;
1205 /* point to the method prot in .gob for failed checks */
1207 out_addline_infile(out,m->line_no);
1209 out_printf(out,"\tg_return_if_fail (");
1211 out_printf(out,"\tg_return_val_if_fail (");
1212 switch(ch->chtype) {
1214 out_printf(out,"%s != NULL",fa->name);
1215 checked_null = TRUE;
1218 s = make_pre_macro(fa->atype->name,"IS");
1220 out_printf(out,"%s (%s)",s,fa->name);
1222 /* if not check null, null may be valid */
1223 out_printf(out,"!(%s) || %s (%s)",fa->name,s,
1228 out_printf(out,"%s < %s",fa->name,ch->number);
1231 out_printf(out,"%s > %s",fa->name,ch->number);
1234 out_printf(out,"%s <= %s",fa->name,ch->number);
1237 out_printf(out,"%s >= %s",fa->name,ch->number);
1240 out_printf(out,"%s == %s",fa->name,ch->number);
1243 out_printf(out,"%s != %s",fa->name,ch->number);
1247 out_printf(out, ");\n");
1249 out_printf(out, ", (");
1250 print_type(out, m->mtype, TRUE);
1251 out_printf(out, ")%s);\n",
1252 m->onerror?m->onerror:"0");
1258 print_preconditions(Method *m)
1262 for(li=m->args;li;li=g_list_next(li)) {
1263 FuncArg *fa = li->data;
1268 out_addline_outfile(out);
1272 print_destructor(char *self_id, Variable *v)
1276 if(v->destructor == NULL)
1279 if(v->scope == PRIVATE_SCOPE)
1280 root = g_strconcat(self_id, "->_priv", NULL);
1282 root = g_strdup(self_id);
1284 if(v->destructor_simple) {
1285 if(v->destructor_line > 0)
1286 out_addline_infile(out, v->destructor_line);
1288 out_printf(out, "\tif(%s->%s) "
1289 "((*(void (*)(void *))%s)) (%s->%s);\n",
1290 root, v->id, v->destructor, root, v->id);
1292 if(v->destructor_line > 0)
1293 out_addline_outfile(out);
1295 out_printf(out, "#define VAR (%s->%s)\n", root, v->id);
1296 out_printf(out, "\t{\n\t%s *self G_GNUC_UNUSED = %s;\n",
1298 if(v->destructor_line > 0)
1299 out_addline_infile(out, v->destructor_line);
1301 out_printf(out, "\t%s}\n", v->destructor);
1303 if(v->destructor_line > 0)
1304 out_addline_outfile(out);
1305 out_printf(out, "#undef VAR\n");
1311 /* put in code if it's needed */
1313 put_in_gen_code(Method *m)
1315 if(m->method == OVERRIDE_METHOD &&
1316 strcmp(m->id, "finalize")==0) {
1317 if(privates > 0 || destructors > 0) {
1318 out_printf(out,"\t%s *___self = %s (%s);\n",
1319 typebase, macrobase,
1320 ((FuncArg *)m->args->data)->name);
1322 if(destructors > 0) {
1324 for(li = ((Class *)class)->nodes;
1328 if(n->type == VARIABLE_NODE)
1329 print_destructor("___self",
1334 out_printf(out,"\tg_free (___self->_priv);\n"
1335 "\t___self->_priv = NULL;\n",
1337 ((FuncArg *)m->args->data)->name,
1339 ((FuncArg *)m->args->data)->name);
1345 print_method_body(Method *m, int pre)
1347 out_printf(out,"{\n");
1349 print_preconditions(m);
1353 /* Note: the trailing }'s are on one line, this is so
1354 that we get the no return warning correctly and point to
1355 the correct line in the .gob file, yes this is slightly
1356 ugly in the .c file, but that is not supposed to be
1357 human readable anyway. */
1359 out_printf(out, "{\n");
1361 out_addline_infile(out, m->ccode_line);
1362 out_printf(out, "\t%s}", m->cbuf);
1365 out_printf(out, "}\n");
1368 out_addline_outfile(out);
1372 put_signal_args(Method *m)
1376 for(ali = m->gtktypes->next,li=m->args->next;
1378 li=li->next, ali=ali->next) {
1379 FuncArg *fa = li->data;
1380 const char *cast = get_cast(ali->data,FALSE);
1381 /* we should have already proved before that
1382 the we know all the types */
1385 out_printf(out,",\n\t\t(%s)%s",cast,
1391 get_arg_names_for_macro(Method *m)
1395 GString *gs = g_string_new(NULL);
1397 for(li=m->args;li;li=g_list_next(li)) {
1398 FuncArg *arg = li->data;
1399 g_string_sprintfa(gs, "%s___%s", p, arg->name);
1403 g_string_free(gs, FALSE);
1408 put_method(Method *m)
1412 is_void = (strcmp(m->mtype->name,"void")==0 &&
1413 m->mtype->stars == 0);
1414 out_printf(out,"\n");
1415 doc = get_gtk_doc(m->id);
1417 out_printf(out, "%s", doc);
1421 case REGULAR_METHOD:
1423 out_addline_infile(out,m->line_no);
1424 if(m->scope == PRIVATE_SCOPE)
1425 print_method(out,"static ","\n",""," ","\n",
1427 else /* PUBLIC, PROTECTED */
1428 print_method(out, "", "\n", "", " ", "\n",
1430 print_method_body(m, TRUE);
1432 case SIGNAL_FIRST_METHOD:
1433 case SIGNAL_LAST_METHOD:
1435 out_addline_infile(out,m->line_no);
1436 if(m->scope == PRIVATE_SCOPE)
1437 print_method(out,"static ","\n",""," ","\n",
1439 else /* PUBLIC, PROTECTED */
1440 print_method(out,"","\n",""," ","\n",m,FALSE,FALSE);
1441 out_addline_outfile(out);
1442 out_printf(out,"{\n");
1443 s = g_strdup(m->id);
1445 if(strcmp(m->mtype->name,"void")==0 &&
1446 m->mtype->stars==0) {
1447 print_preconditions(m);
1448 if(((FuncArg *)m->args->data)->name)
1449 out_printf(out,"\tgtk_signal_emit (GTK_OBJECT (%s),\n"
1450 "\t\tobject_signals[%s_SIGNAL]",
1451 ((FuncArg *)m->args->data)->name,s);
1453 out_printf(out,");\n}\n");
1455 out_printf(out,"\t");
1456 print_type(out,m->mtype,TRUE);
1457 out_printf(out,"return_val;\n");
1458 print_preconditions(m);
1459 out_printf(out,"\tgtk_signal_emit (GTK_OBJECT (%s),\n"
1460 "\t\tobject_signals[%s_SIGNAL]",
1461 ((FuncArg *)m->args->data)->name,s);
1463 out_printf(out,",\n\t\t&return_val);\n"
1464 "\treturn return_val;\n}\n");
1470 out_addline_infile(out,m->line_no);
1471 print_method(out,"static ","\n___real_",""," ","\n",
1473 print_method_body(m,FALSE);
1475 case VIRTUAL_METHOD:
1477 out_addline_infile(out,m->line_no);
1478 if(m->scope==PRIVATE_SCOPE)
1479 print_method(out,"static ","\n",""," ","\n",
1481 else /* PUBLIC, PROTECTED */
1482 print_method(out,"","\n",""," ","\n",m,FALSE,FALSE);
1483 out_addline_outfile(out);
1484 out_printf(out,"{\n"
1485 "\t%sClass *klass;\n",typebase);
1486 print_preconditions(m);
1487 out_printf(out,"\tklass = %s_CLASS(GTK_OBJECT(%s)->klass);\n\n"
1488 "\tif(klass->%s)\n",
1489 macrobase, ((FuncArg *)m->args->data)->name, m->id);
1490 if(strcmp(m->mtype->name,"void")==0 &&
1491 m->mtype->stars==0) {
1493 out_printf(out,"\t\t(*klass->%s)(%s",m->id,
1494 ((FuncArg *)m->args->data)->name);
1495 for(li=m->args->next;li;li=g_list_next(li)) {
1496 FuncArg *fa = li->data;
1497 out_printf(out,",%s",fa->name);
1499 out_printf(out,");\n}\n");
1502 out_printf(out,"\t\treturn (*klass->%s)(%s",m->id,
1503 ((FuncArg *)m->args->data)->name);
1504 for(li=m->args->next;li;li=g_list_next(li)) {
1505 FuncArg *fa = li->data;
1506 out_printf(out,",%s",fa->name);
1508 out_printf(out,");\n"
1511 print_type(out,m->mtype,TRUE);
1512 out_printf(out,")(%s);\n}\n",
1513 m->onerror?m->onerror:"0");
1519 out_addline_infile(out,m->line_no);
1520 print_method(out,"static ","\n___real_",""," ","\n",
1522 print_method_body(m,FALSE);
1524 case OVERRIDE_METHOD:
1528 out_addline_infile(out,m->line_no);
1529 print_method(out,"static ","\n",""," ","\n",
1531 s = replace_sep(m->otype,'_');
1533 args = get_arg_names_for_macro(m);
1535 out_printf(out,"#define PARENT_HANDLER(%s) \\\n"
1536 "\t{ if(%s_CLASS(parent_class)->%s) \\\n"
1537 "\t\t(* %s_CLASS(parent_class)->%s)(%s); }\n",
1538 args,s,m->id,s,m->id,args);
1540 out_printf(out,"#define PARENT_HANDLER(%s) \\\n"
1541 "\t((%s_CLASS(parent_class)->%s)? \\\n"
1542 "\t\t(* %s_CLASS(parent_class)->%s)(%s): \\\n"
1544 args,s,m->id,s,m->id,args);
1545 out_printf(out,"(");
1546 print_type(out,m->mtype,TRUE);
1547 out_printf(out,")%s))\n",
1548 m->onerror?m->onerror:"0");
1552 print_method_body(m,TRUE);
1553 out_printf(out,"#undef PARENT_HANDLER\n");
1563 char *outfile,*outfileh,*outfileph;
1566 outfile = g_strconcat(filebase,".c",NULL);
1568 outfile = g_strconcat(filebase,".cc",NULL);
1569 if(no_touch_headers)
1570 outfileh = g_strconcat("#gob#",filebase,".h#gob#",NULL);
1572 outfileh = g_strconcat(filebase,".h",NULL);
1574 if((privates>0 || protecteds>0 || always_private_header) &&
1576 outfileph = g_strconcat(filebase,"-private.h",NULL);
1582 devnull = fopen("/dev/null","w");
1584 g_error("Cannot open null device",NULL);
1591 out = fopen(outfile,"w");
1593 g_error("Cannot open outfile: %s",outfile);
1595 outh = fopen(outfileh,"w");
1597 g_error("Cannot open outfile: %s",outfileh);
1600 outph = fopen(outfileph,"w");
1602 g_error("Cannot open outfile: %s",outfileh);
1609 put_argument_nongnu_wrappers(Class *c)
1616 for(li=c->nodes;li;li=g_list_next(li)) {
1618 Argument *a = (Argument *)n;
1621 if(n->type != ARGUMENT_NODE)
1623 s = g_strdup(a->name);
1626 cast = get_type(a->atype, TRUE);
1628 cast = g_strdup(get_cast(a->gtktype, TRUE));
1632 out_printf(outh, "#define %s_ARG_%s(arg) \t"
1633 "\"%s\",(%s)(arg)\n",
1634 macrobase, s, a->name, cast);
1636 out_printf(outh, "#define %s_GET_ARG_%s(arg)\t"
1637 "\"%s\",(%s*)(arg)\n",
1638 macrobase, s, a->name, cast);
1641 out_printf(outh, "#define %s_ARG_%s(arg) \t"
1643 macrobase, s, a->name);
1645 out_printf(outh, "#define %s_GET_ARG_%s(arg)\t"
1647 macrobase, s, a->name);
1655 put_argument_gnu_wrappers(Class *c)
1662 for(li=c->nodes;li;li=g_list_next(li)) {
1664 Argument *a = (Argument *)n;
1667 if(n->type != ARGUMENT_NODE)
1669 s = g_strdup(a->name);
1672 cast = get_type(a->atype,TRUE);
1674 cast = g_strdup(get_cast(a->gtktype,TRUE));
1677 out_printf(outh, "#define %s_ARG_%s(arg) \t"
1678 "\"%s\",({%sz = (arg); z;})\n",
1679 macrobase, s, a->name, cast);
1681 out_printf(outh, "#define %s_GET_ARG_%s(arg)\t"
1682 "\"%s\",({%s*z = (arg); z;})\n",
1683 macrobase, s, a->name, cast);
1686 out_printf(outh, "#define %s_ARG_%s(arg) \t"
1688 macrobase, s, a->name);
1690 out_printf(outh, "#define %s_GET_ARG_%s(arg)\t"
1692 macrobase, s, a->name);
1700 print_ccode_block(CCode *cc)
1703 switch(cc->cctype) {
1705 /* HT code is printed exactly like normal header
1706 code but is printed before */
1709 out_printf(fp,"\n");
1712 /* AT code is printed exactly like normal 'all'
1713 code but is printed before */
1716 out_printf(outph,"\n");
1717 out_printf(outph,"%s\n",cc->cbuf);
1718 out_addline_infile(outph,cc->line_no);
1719 out_addline_outfile(outph);
1721 out_printf(outh,"\n");
1722 out_printf(outh,"%s\n",cc->cbuf);
1724 out_printf(fp,"\n");
1725 out_addline_infile(fp,cc->line_no);
1730 out_printf(fp,"\n");
1731 out_addline_infile(fp,cc->line_no);
1738 out_printf(fp,"\n");
1739 out_addline_infile(fp,cc->line_no);
1742 out_printf(fp,"%s\n",cc->cbuf);
1743 if(cc->cctype == C_CCODE ||
1744 cc->cctype == A_CCODE ||
1745 cc->cctype == AT_CCODE ||
1746 cc->cctype == PH_CCODE)
1747 out_addline_outfile(fp);
1751 print_class_block(Class *c)
1755 gboolean printed_private = FALSE;
1757 out_printf(out,"/* utility types we may need */\n");
1758 out_printf(out,"typedef struct { "
1759 "gpointer a; gpointer b; "
1760 "} ___twopointertype;\n");
1761 out_printf(out,"typedef struct { "
1762 "gpointer a; gpointer b; "
1764 "} ___threepointertype;\n");
1766 out_printf(outh, "\n/*\n"
1767 " * Type checking and casting macros\n"
1769 out_printf(outh,"#define %s\t"
1770 "(%s_get_type())\n",
1771 macrotype,funcbase);
1772 out_printf(outh,"#define %s(obj)\t"
1773 "GTK_CHECK_CAST((obj),%s_get_type(),%s)\n",
1774 macrobase,funcbase,typebase);
1775 out_printf(outh,"#define %s_CLASS(klass)\t"
1776 "GTK_CHECK_CLASS_CAST((klass),%s_get_type(),%sClass)\n",
1777 macrobase,funcbase,typebase);
1778 out_printf(outh,"#define %s(obj)\t"
1779 "GTK_CHECK_TYPE((obj), %s_get_type ())\n\n",
1782 out_printf(out, "\n/* self casting macros */\n");
1783 out_printf(out, "#define SELF(x) %s(x)\n", macrobase);
1784 out_printf(out, "#define IS_SELF(x) %s(x)\n", macrois);
1785 out_printf(out, "#define SELF_CLASS(x) %s_CLASS(x)\n\n", macrobase);
1788 out_printf(outh, "\n/* Private structure type */\n");
1789 out_printf(outh,"typedef struct _%sPrivate %sPrivate;\n",
1793 out_printf(outh, "\n/*\n"
1794 " * Main object structure\n"
1796 s = replace_sep(c->otype,'_');
1798 out_printf(outh,"#ifndef __TYPEDEF_%s__\n"
1799 "#define __TYPEDEF_%s__\n",s,s);
1801 out_printf(outh,"typedef struct _%s %s;\n"
1802 "#endif\n",typebase,typebase);
1803 out_printf(outh,"struct _%s {\n\t%s __parent__;\n",
1804 typebase,ptypebase);
1805 for(l=c->nodes;l;l=g_list_next(l)) {
1806 static gboolean printed_public = FALSE;
1808 Variable *v = (Variable *)n;
1809 if(n->type == VARIABLE_NODE &&
1810 v->scope == PUBLIC_SCOPE) {
1811 if(!printed_public) {
1812 out_printf(outh,"\t/*< public >*/\n");
1813 printed_public = TRUE;
1815 put_variable((Variable *)n,outh);
1818 /* put protecteds always AFTER publics */
1819 for(l=c->nodes;l;l=g_list_next(l)) {
1821 Variable *v = (Variable *)n;
1822 if(n->type == VARIABLE_NODE &&
1823 v->scope == PROTECTED_SCOPE) {
1824 if(!printed_private) {
1825 out_printf(outh,"\t/*< private >*/\n");
1826 printed_private = TRUE;
1828 put_variable((Variable *)n,outh);
1832 if(!printed_private)
1833 out_printf(outh,"\t/*< private >*/\n");
1834 out_printf(outh,"\t%sPrivate *_priv;\n",typebase);
1836 out_printf(outh,"};\n");
1841 /* if we are to stick this into the private
1842 header, if not stick it directly into the
1849 out_printf(outfp,"struct _%sPrivate {\n",
1851 for(l=c->nodes;l;l=l->next) {
1853 Variable *v = (Variable *)n;
1854 if(n->type == VARIABLE_NODE &&
1855 v->scope == PRIVATE_SCOPE) {
1856 out_addline_infile(outfp,v->line_no);
1857 put_variable(v,outfp);
1860 out_addline_outfile(outfp);
1861 out_printf(outfp,"};\n");
1864 out_printf(outh, "\n/*\n"
1865 " * Class definition\n"
1867 out_printf(outh,"typedef struct _%sClass %sClass;\n",
1870 "struct _%sClass {\n\t%sClass __parent__;\n",
1871 typebase,ptypebase);
1872 for(l=c->nodes;l;l=g_list_next(l)) {
1874 if(n->type == METHOD_NODE)
1875 put_vs_method((Method *)n);
1877 out_printf(outh,"};\n\n");
1879 out_printf(out,"/* here are local prototypes */\n");
1881 out_printf(out,"static void ___object_set_arg "
1882 "(GtkObject *object, GtkArg *arg, "
1884 "static void ___object_get_arg "
1885 "(GtkObject *object, GtkArg *arg, "
1886 "guint arg_id);\n");
1889 out_printf(outh, "\n/*\n"
1890 " * Public methods\n"
1893 out_printf(outh,"guint\t%s_get_type\t(void);\n",funcbase);
1894 for(l=c->nodes;l;l=g_list_next(l)) {
1896 if(n->type == METHOD_NODE) {
1897 put_pub_method((Method *)n);
1898 put_prot_method((Method *)n);
1899 put_priv_method_prot((Method *)n);
1903 /* this idea is less and less apealing to me */
1905 if(!no_signal_connect) {
1907 out_printf(outh, "\n/*\n"
1908 " * Signal connection methods\n"
1912 for(l=c->nodes;l;l=g_list_next(l)) {
1914 if(n->type == METHOD_NODE)
1915 put_signal_connect((Method *)n);
1921 /* argument wrapping macros */
1922 if(arguments>0 && !no_gnu) {
1923 out_printf(outh, "\n/*\n"
1924 " * Argument wrapping macros\n"
1926 out_printf(outh,"#ifdef __GNUC__\n");
1927 put_argument_gnu_wrappers(c);
1928 out_printf(outh,"#else /* __GNUC__ */\n");
1929 put_argument_nongnu_wrappers(c);
1930 out_printf(outh,"#endif /* __GNUC__ */\n\n");
1931 } else if(arguments>0 && no_gnu) {
1932 out_printf(outh, "\n/*\n"
1933 " * Argument wrapping macros\n"
1935 put_argument_nongnu_wrappers(c);
1939 for(l=c->nodes;l;l=g_list_next(l)) {
1941 if(n->type == METHOD_NODE)
1942 add_signal_prots((Method *)n);
1950 if(any_method_to_alias(c)) {
1952 make_method_nongnu_aliases(c);
1954 out_printf(out,"\n#ifdef __GNUC__\n");
1955 make_method_gnu_aliases(c);
1956 out_printf(out,"#else /* __GNUC__ */\n");
1957 make_method_nongnu_aliases(c);
1958 out_printf(out,"#endif /* __GNUC__ */\n\n");
1962 out_printf(out,"/* a macro for creating a new object of our type */\n");
1964 "#define GET_NEW ((%s *)gtk_type_new(%s_get_type()))\n\n",
1965 typebase, funcbase);
1970 add_getset_arg(c, TRUE);
1971 add_getset_arg(c, FALSE);
1974 for(l=c->nodes;l;l=g_list_next(l)) {
1976 if(n->type == METHOD_NODE) {
1977 put_method((Method *)n);
1981 add_bad_hack_to_avoid_unused_warnings(c);
1985 print_version_macros(void)
1987 int major=0,minor=0,pl=0;
1988 sscanf(VERSION,"%d.%d.%d",&major,&minor,&pl);
1990 out_printf(out, "#define GOB_VERSION_MAJOR %d\n", major);
1991 out_printf(out, "#define GOB_VERSION_MINOR %d\n", minor);
1992 out_printf(out, "#define GOB_VERSION_PATCHLEVEL %d\n\n", pl);
1996 print_file_comments(void)
2000 out_printf(outh, "/* Generated by GOB (v%s)"
2001 " (do not edit directly) */\n\n", VERSION);
2003 out_printf(outph,"/* Generated by GOB (v%s)"
2004 " (do not edit directly) */\n\n", VERSION);
2005 out_printf(out,"/* Generated by GOB (v%s) on %s"
2006 " (do not edit directly) */\n\n",
2007 VERSION, ctime(&curtime));
2011 print_includes(void)
2013 gboolean found_header;
2016 p = g_strconcat(filebase, ".h", NULL);
2017 found_header = TRUE;
2018 if(!g_list_find_custom(include_files, p, (GCompareFunc)strcmp)) {
2019 out_printf(out, "#include \"%s.h\"\n\n", filebase);
2020 found_header = FALSE;
2024 /* if we are creating a private header see if it was included */
2026 p = g_strconcat(filebase, "-private.h", NULL);
2027 if(!g_list_find_custom(include_files,p,(GCompareFunc)strcmp)) {
2028 out_printf(out,"#include \"%s-private.h\"\n\n",
2032 "Implicit private header include "
2034 "\tsource file, while public "
2035 "header is at a custom location, "
2037 "\texplicitly include "
2038 "the private header below the "
2046 print_header_prefixes(void)
2050 p = replace_sep(((Class *)class)->otype, '_');
2052 out_printf(outh, "#ifndef __%s_H__\n#define __%s_H__\n\n", p, p);
2054 out_printf(outph, "#ifndef __%s_PRIVATE_H__\n"
2055 "#define __%s_PRIVATE_H__\n\n"
2056 "#include \"%s.h\"\n\n", p, p, filebase);
2060 out_printf(outh, "#ifdef __cplusplus\n"
2062 "#endif /* __cplusplus */\n\n");
2064 out_printf(outph, "#ifdef __cplusplus\n"
2066 "#endif /* __cplusplus */\n\n");
2071 print_header_postfixes(void)
2074 out_printf(outh,"\n#ifdef __cplusplus\n"
2076 "#endif /* __cplusplus */\n");
2077 out_printf(outh,"\n#endif");
2080 out_printf(outph,"\n#ifdef __cplusplus\n"
2082 "#endif /* __cplusplus */\n");
2083 out_printf(outph,"\n#endif");
2092 /* print the AT_CCODE blocks */
2093 for(li=nodes;li;li=g_list_next(li)) {
2094 Node *node = li->data;
2095 if(node->type == CCODE_NODE) {
2096 CCode *cc = (CCode *)node;
2097 if(cc->cctype==AT_CCODE)
2098 print_ccode_block((CCode *)node);
2104 print_header_top(void)
2108 /* mandatory include */
2109 out_printf(outh,"#include <gtk/gtk.h>\n\n");
2111 /* print the HT_CCODE blocks */
2112 for(li=nodes;li;li=g_list_next(li)) {
2113 Node *node = li->data;
2114 if(node->type == CCODE_NODE) {
2115 CCode *cc = (CCode *)node;
2116 if(cc->cctype==HT_CCODE)
2117 print_ccode_block((CCode *)node);
2123 generate_outfiles(void)
2127 print_file_comments();
2133 print_header_prefixes();
2135 print_version_macros();
2139 for(li=nodes;li;li=g_list_next(li)) {
2140 Node *node = li->data;
2141 if(node->type == CCODE_NODE) {
2142 CCode *cc = (CCode *)node;
2143 if(cc->cctype!=HT_CCODE)
2144 print_ccode_block((CCode *)node);
2145 } else if(node->type == CLASS_NODE) {
2146 print_class_block((Class *)node);
2148 g_assert_not_reached();
2151 print_header_postfixes();
2157 fprintf(stderr,"Gob version %s\n\n",VERSION);
2158 fprintf(stderr,"Options:\n"
2159 "\t--help,-h,-? Display this help\n"
2160 "\t--version Display version\n"
2161 "\t--exit-on-warn,-w Exit with an error on warnings\n"
2162 "\t--no-exit-on-warn Don't exit on warnings [default]\n"
2163 "\t--for-cpp Create C++ files\n"
2164 "\t--no-extern-c Never print extern \"C\" into the "
2166 "\t--no-gnu Never use GNU extentions\n"
2167 "\t--no-touch-headers Don't touch headers unless they "
2169 "\t--always-private-header Always create a private header "
2171 "\t even if it would be empty\n"
2172 "\t--no-private-header Don't create a private header, "
2174 "\t structure and protected "
2175 "prototypes inside c file\n"
2176 "\t--no-write,-n Don't write output files, just "
2178 "\t--no-lines Don't print '#line' to output\n");
2182 parse_options(int argc, char *argv[])
2185 int got_file = FALSE;
2186 int no_opts = FALSE;
2190 for(i=1;i<argc;i++) {
2191 if(no_opts || argv[i][0]!='-') {
2194 fprintf(stderr, "Specify only one file!\n");
2200 } else if(strcmp(argv[i],"--help")==0) {
2203 } else if(strcmp(argv[i],"--version")==0) {
2204 fprintf(stderr, "Gob version %s\n", VERSION);
2206 } else if(strcmp(argv[i], "--exit-on-warn")==0) {
2207 exit_on_warn = TRUE;
2208 } else if(strcmp(argv[i], "--no-exit-on-warn")==0) {
2209 exit_on_warn = FALSE;
2210 } else if(strcmp(argv[i], "--for-cpp")==0) {
2212 } else if(strcmp(argv[i], "--no-touch-headers")==0) {
2213 no_touch_headers = TRUE;
2214 } else if(strcmp(argv[i], "--always-private-header")==0) {
2215 no_private_header = FALSE;
2216 always_private_header = TRUE;
2217 } else if(strcmp(argv[i], "--no-private-header")==0) {
2218 always_private_header = FALSE;
2219 no_private_header = TRUE;
2220 } else if(strcmp(argv[i], "--no-gnu")==0) {
2222 } else if(strcmp(argv[i], "--no-extern-c")==0) {
2224 } else if(strcmp(argv[i], "--no-write")==0) {
2226 } else if(strcmp(argv[i], "--no-lines")==0) {
2228 } else if(strcmp(argv[i], "--")==0) {
2229 /*further arguments are files*/
2231 } else if(strncmp(argv[i], "--",2)==0) {
2232 /*unknown long option*/
2233 fprintf(stderr, "Unknown option '%s'!\n", argv[i]);
2237 /*by now we know we have a string starting with
2238 - which is a short option string*/
2239 char *p = argv[i]+1;
2240 for(p=argv[i]+1; *p; p++) {
2254 "Unknown option '%c'!\n", *p);
2263 /* this is a somewhat ugly hack, but it appears to work */
2265 compare_and_move_header(void)
2267 char *hfnew = g_strconcat("#gob#", filebase, ".h#gob#", NULL);
2268 char *hf = g_strconcat(filebase, ".h", NULL);
2270 if(stat(hf,&s)==0) {
2272 s = g_strdup_printf("cmp '%s' '%s' > /dev/null", hf, hfnew);
2274 if(unlink(hfnew)!=0)
2276 "Can't remove new header file", 0);
2284 print_error(FALSE, "Can't remove old header file", 0);
2286 if(rename(hfnew,hf)!=0)
2287 print_error(FALSE, "Can't rename new header file", 0);
2293 main(int argc, char *argv[])
2295 parse_options(argc, argv);
2298 yyin = fopen(filename, "r");
2300 fprintf(stderr, "Error: can't open file '%s'\n",
2309 g_error("Parsing errors, quitting");
2311 print_error(FALSE, " no class defined", 0);
2314 exit_on_error = FALSE;
2316 signals = count_signals((Class *)class);
2317 arguments = count_arguments((Class *)class);
2318 overrides = count_overrides((Class *)class);
2319 privates = count_privates((Class *)class);
2320 protecteds = count_protecteds((Class *)class);
2321 destructors = count_destructors((Class *)class);
2322 initializers = count_initializers((Class *)class);
2325 make_inits((Class *)class);
2327 make_finalize((Class *)class);
2328 check_bad_symbols((Class *)class);
2329 check_duplicate_symbols((Class *)class);
2330 check_duplicate_signals_args((Class *)class);
2331 check_public_new((Class *)class);
2332 check_vararg((Class *)class);
2333 check_firstarg((Class *)class);
2334 check_nonvoidempty((Class *)class);
2335 check_signal_args((Class *)class);
2336 check_argument_types((Class *)class);
2338 exit_on_error = TRUE;
2345 generate_outfiles();
2356 if(no_touch_headers && !no_write)
2357 compare_and_move_header();