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,
31 #include "treefuncs.h"
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
73 /* the special variable types we need to define */
74 static gboolean special_array[SPECIAL_LAST] = {0};
75 static gboolean any_special = FALSE;
82 gboolean no_touch_headers = FALSE;
83 gboolean for_cpp = FALSE;
84 gboolean no_gnu = FALSE;
85 gboolean exit_on_warn = FALSE;
86 gboolean exit_on_error = TRUE;
87 gboolean got_error = FALSE;
88 gboolean always_private_header = FALSE;
89 gboolean no_private_header = FALSE;
90 gboolean no_extern_c = FALSE;
91 gboolean no_write = FALSE;
92 gboolean no_lines = FALSE;
97 filebase = replace_sep(((Class *)class)->otype, '-');
100 funcbase = replace_sep(((Class *)class)->otype, '_');
103 pfuncbase = replace_sep(((Class *)class)->ptype, '_');
104 g_strdown(pfuncbase);
106 macrobase = replace_sep(((Class *)class)->otype, '_');
109 macrois = make_pre_macro(((Class *)class)->otype, "IS");
110 macrotype = make_pre_macro(((Class *)class)->otype, "TYPE");
112 typebase = remove_sep(((Class *)class)->otype);
114 ptypebase = remove_sep(((Class *)class)->ptype);
118 get_type(Type *t, gboolean postfix_to_stars)
125 s = remove_sep(t->name);
126 gs = g_string_new(s);
130 if(postfix_to_stars) {
132 /*XXX: this is ugly perhaps we can do this whole postfix thing
133 in a nicer way, we just count the number of '[' s and from
134 that we deduce the number of dimensions, so that we can print
136 for(p=t->postfix; p && *p; p++)
137 if(*p == '[') extra++;
139 g_string_append_c(gs, ' ');
141 for(i=0; i<(t->stars+extra); i++)
142 g_string_append_c(gs, '*');
145 g_string_free(gs, FALSE);
150 get_gtk_doc(char *id)
157 val = g_hash_table_lookup(gtk_doc_hash, id);
159 return g_strdup_printf("/**\n * %s_%s:\n%s **/\n",
161 s = g_strconcat(funcbase, "_", id, NULL);
162 val = g_hash_table_lookup(gtk_doc_hash, s);
165 return g_strdup_printf("/**\n * %s_%s:\n%s **/\n",
171 print_type(FILE *fp, Type *t, gboolean postfix_to_stars)
175 s = get_type(t, postfix_to_stars);
176 out_printf(fp, "%s", s);
182 print_method(FILE *fp, char *typeprefix, char *nameprefix,
184 char *namepostfix, char *postfix, Method *m,
185 gboolean one_arg_per_line,
186 gboolean no_funcbase)
190 out_printf(fp, "%s", typeprefix);
191 print_type(fp, m->mtype, TRUE);
193 out_printf(fp, "%s%s%s%s(",
194 nameprefix, subnameprefix, m->id, namepostfix);
196 out_printf(fp, "%s%s_%s%s%s(",
197 nameprefix, funcbase, subnameprefix, m->id,
201 for(li=m->args; li; li=g_list_next(li)) {
202 FuncArg *arg = li->data;
203 print_type(fp, arg->atype, FALSE);
205 out_printf(fp, "%s%s,%s", arg->name,
207 arg->atype->postfix:"",
208 one_arg_per_line?"\n\t\t\t\t\t":" ");
210 out_printf(fp, "%s%s", arg->name,
212 arg->atype->postfix:"");
215 out_printf(fp, ",%s...",
216 one_arg_per_line?"\n\t\t\t\t\t":" ");
218 out_printf(fp, "void");
220 out_printf(fp, ")%s", postfix);
224 any_method_to_alias(Class *c)
228 for(li=c->nodes;li;li=g_list_next(li)) {
229 Node *node = li->data;
230 if(node->type == METHOD_NODE) {
231 Method *m = (Method *)node;
233 if(m->method == INIT_METHOD ||
234 m->method == CLASS_INIT_METHOD ||
235 m->method == OVERRIDE_METHOD)
246 make_method_gnu_aliases(Class *c)
250 for(li=c->nodes;li;li=g_list_next(li)) {
251 Node *node = li->data;
252 if(node->type == METHOD_NODE) {
253 Method *m = (Method *)node;
255 if(m->method == INIT_METHOD ||
256 m->method == CLASS_INIT_METHOD ||
257 m->method == OVERRIDE_METHOD)
260 /* in C++ mode don't alias new */
261 if(for_cpp && strcmp(m->id, "new")==0)
264 out_printf(out, "static const typeof(&%s_%s) %s "
265 "__attribute__ ((__unused__)) "
266 "= %s_%s;\n", funcbase, m->id, m->id,
268 out_printf(out, "#define %s(args...) "
269 "%s_%s(##args)\n", m->id, funcbase, m->id);
275 make_method_nongnu_aliases(Class *c)
279 for(li=c->nodes; li; li=g_list_next(li)) {
280 Node *node = li->data;
281 if(node->type == METHOD_NODE) {
282 Method *m = (Method *)node;
284 if(m->method == INIT_METHOD ||
285 m->method == CLASS_INIT_METHOD ||
286 m->method == OVERRIDE_METHOD)
289 /* in C++ mode don't alias new */
290 if(for_cpp && strcmp(m->id, "new")==0)
293 print_method(out, "static ", "(* ", "", ") ", "",
295 out_printf(out, " = %s_%s;\n", funcbase, m->id);
303 add_bad_hack_to_avoid_unused_warnings(Class *c)
307 /* if we haven't had any methods, just return */
312 out_printf(out,"\n\n#ifndef __GNUC__\n");
314 "/*REALLY BAD HACK\n"
315 " This is to avoid unused warnings if you don't call\n"
316 " some method. I need to find a better way to do\n"
317 " this, not needed in GCC since we use some gcc\n"
318 " extentions to make saner, faster code */\n"
320 "___%s_really_bad_hack_to_avoid_warnings(void)\n"
322 for(li=c->nodes;li;li=g_list_next(li)) {
323 Node *node = li->data;
324 if(node->type == METHOD_NODE) {
325 Method *m = (Method *)node;
327 if(m->method == INIT_METHOD ||
328 m->method == CLASS_INIT_METHOD ||
329 m->method == OVERRIDE_METHOD)
332 /* in C++ mode we don't alias new */
333 if(for_cpp && strcmp(m->id,"new")==0)
336 out_printf(out,"\t((void (*)(void))%s)();\n",m->id);
339 out_printf(out, "\t___%s_really_bad_hack_to_avoid_warnings();\n",
342 out_printf(out,"}\n#endif /* __GNUC__ */\n\n");
344 out_printf(out,"}\n\n");
348 put_variable(Variable *v, FILE *fp)
351 print_type(fp,v->vtype,FALSE);
352 out_printf(fp,"%s%s;",v->id,
354 v->vtype->postfix:"");
355 if(v->scope == PROTECTED_SCOPE)
356 out_printf(fp," /* protected */");
361 put_vs_method(Method *m)
363 if(m->method != SIGNAL_LAST_METHOD &&
364 m->method != SIGNAL_FIRST_METHOD &&
365 m->method != VIRTUAL_METHOD)
368 /* if a signal mark it as such */
369 if(m->method != VIRTUAL_METHOD)
370 print_method(outh,"\t/*signal*/","(* ","",") ",";\n",m,
373 print_method(outh,"\t","(* ","",") ",";\n",m,FALSE,TRUE);
377 put_pub_method(Method *m)
379 if(m->scope != PUBLIC_SCOPE)
382 print_method(outh,"","\t","","\t",";\n",m,TRUE,FALSE);
385 /* I'm starting not to like this idea */
388 put_signal_connect(Method *m)
390 if(m->method != SIGNAL_LAST_METHOD &&
391 m->method != SIGNAL_FIRST_METHOD)
394 out_printf(outh, "guint \t%s_%s__connect_full\t(%s *object,\n"
395 "\t\t\t\t\tconst char *name,\n"
396 "\t\t\t\t\tGtkSignalFunc func,\n"
397 "\t\t\t\t\tGtkCallbackMarshal marshal,\n"
398 "\t\t\t\t\tgpointer data,\n"
399 "\t\t\t\t\tGtkDestroyNotify destroy_func,\n"
400 "\t\t\t\t\tgboolean object_signal,\n"
401 "\t\t\t\t\tgboolean after);\n",
402 funcbase, m->id, typebase);
404 out_printf(outh, "#define %s_%s__connect(object,name,func,data) "
405 "%s_%s__connect_full((object),(name),(func),NULL,"
406 "(data),NULL,FALSE,FALSE)\n",
407 funcbase, m->id, funcbase, m->id);
408 out_printf(outh, "#define %s_%s__connect_after(object,name,func,data) "
409 "%s__connect_%s_full((object),(name),(func),NULL,"
410 "(data),NULL,FALSE,TRUE)\n",
411 funcbase, m->id, funcbase, m->id);
413 out_printf(outh, "guint \t%s_%s__connect_while_alive\t(%s *object,\n"
414 "\t\t\t\t\tconst char *name,\n"
415 "\t\t\t\t\tGtkSignalFunc func,\n"
416 "\t\t\t\t\tgpointer data,\n"
417 "\t\t\t\t\tGtkObject *alive_object);\n\n",
418 funcbase, m->id, typebase);
424 put_prot_method(Method *m)
426 if(m->scope != PROTECTED_SCOPE)
430 print_method(outph,"","\t","","\t",";\n",m,FALSE,FALSE);
432 print_method(out,"","\t","","\t",";\n",m,FALSE,FALSE);
436 put_priv_method_prot(Method *m)
438 if(m->method == SIGNAL_LAST_METHOD ||
439 m->method == SIGNAL_FIRST_METHOD ||
440 m->method == VIRTUAL_METHOD) {
443 "static ", "___real_", "", " ", ";\n",
447 if(m->scope == PRIVATE_SCOPE ||
448 m->method == INIT_METHOD ||
449 m->method == CLASS_INIT_METHOD ||
450 (m->method == OVERRIDE_METHOD &&
452 print_method(out, "static ", "", "", " ",
453 no_gnu?";\n":" G_GNUC_UNUSED;\n",
458 make_func_arg(char *typename, int is_class, char *name)
465 tn = g_strconcat(typename,":Class",NULL);
467 tn = g_strdup(typename);
469 type = new_type(1,tn,NULL);
470 node = new_funcarg((Type *)type,name,NULL);
471 return g_list_prepend(NULL, node);
475 make_inits(Class *cl)
477 int got_class_init = FALSE;
478 int got_init = FALSE;
481 for(li=cl->nodes;li;li=g_list_next(li)) {
483 if(n->type == METHOD_NODE) {
484 Method *m = (Method *)n;
485 if(m->method == INIT_METHOD) {
487 print_error(FALSE,"init defined more then once",m->line_no);
489 } else if(m->method == CLASS_INIT_METHOD) {
491 print_error(FALSE,"class_init defined more then once",m->line_no);
492 got_class_init = TRUE;
496 if(!got_class_init) {
497 node = new_method(NO_SCOPE, CLASS_INIT_METHOD,
498 (Type *)new_type(0, g_strdup("void"),NULL),
499 NULL, NULL, NULL, g_strdup("class_init"),
500 make_func_arg(cl->otype, TRUE, g_strdup("c")),
501 NULL, NULL, NULL, 0, 0, FALSE);
502 cl->nodes = g_list_prepend(cl->nodes,node);
505 node = new_method(NO_SCOPE, INIT_METHOD,
506 (Type *)new_type(0, g_strdup("void"),NULL),
507 NULL, NULL, NULL, g_strdup("init"),
508 make_func_arg(cl->otype, FALSE, g_strdup("o")),
509 NULL, NULL, NULL, 0, 0, FALSE);
510 cl->nodes = g_list_prepend(cl->nodes,node);
515 make_finalize(Class *cl)
517 int got_finalize = FALSE;
520 for(li=cl->nodes;li;li=g_list_next(li)) {
522 if(n->type == METHOD_NODE) {
523 Method *m = (Method *)n;
524 if(m->method == OVERRIDE_METHOD &&
525 strcmp(m->id, "finalize")==0) {
526 if(strcmp(m->otype, "Gtk:Object")==0) {
530 print_error(FALSE,"finalize method override "
531 "of class other then Gtk:Object",
537 node = new_method(NO_SCOPE, OVERRIDE_METHOD,
538 (Type *)new_type(0,g_strdup("void"),NULL),
539 g_strdup("Gtk:Object"),
540 NULL, NULL, g_strdup("finalize"),
541 make_func_arg("Gtk:Object",FALSE,g_strdup("o")),
543 g_strdup("PARENT_HANDLER (o);\n"),
545 cl->nodes = g_list_append(cl->nodes,node);
551 /* hash of method -> name of signal prototype */
552 static GHashTable *marsh = NULL;
554 /* list of methods with different signal prototypes,
555 we check this list if we can use a signal prototype of a
556 previous signal method, there are only uniques here */
557 static GList *eq_signal_methods = NULL;
559 /* compare a list of strings */
561 is_list_equal(GList *a, GList *b)
563 for(;a && b; a=a->next, b=b->next) {
564 if(strcmp(a->data,b->data)!=0) {
568 /* the the lists were different length */
575 find_same_type_signal(Method *m)
578 for(li=eq_signal_methods;li;li=li->next) {
579 Method *mm = li->data;
580 if(is_list_equal(mm->gtktypes,m->gtktypes))
587 print_signal_marsal_args(Method *m)
589 if(strcmp(m->gtktypes->next->data, "NONE")!=0) {
592 for(i=0,li=m->gtktypes->next;li;
593 i++,li=g_list_next(li)) {
595 out_printf(out, ",\n\t\tGTK_VALUE_%s(args[%d])",
598 out_printf(out, ",\n\t\t(%s)"
599 "GTK_VALUE_%s(args[%d])",
600 get_cast(li->data, FALSE),
605 out_printf(out, ",\n\t\tfunc_data);\n}\n\n");
610 add_signal_prots(Method *m)
617 if(m->method != SIGNAL_LAST_METHOD &&
618 m->method != SIGNAL_FIRST_METHOD)
622 marsh = g_hash_table_new(NULL,NULL);
624 if(strcmp(m->gtktypes->data, "NONE")==0 &&
625 strcmp(m->gtktypes->next->data, "NONE")==0)
628 /* if we already did a signal prototype just use that */
629 mm = find_same_type_signal(m);
631 s = g_hash_table_lookup(marsh,mm);
632 g_hash_table_insert(marsh,m,s);
636 s = g_strdup_printf("Sig%d",sig++);
638 g_hash_table_insert(marsh, m, s);
639 eq_signal_methods = g_list_prepend(eq_signal_methods, m);
641 /* we know that we'll know all the gtktypes (so get_cast can't fail) */
642 out_printf(out, "\ntypedef %s (*___%s) (%s *, ",
643 get_cast(m->gtktypes->data, FALSE), s, typebase);
645 if(strcmp(m->gtktypes->next->data, "NONE")!=0) {
646 for(li=m->gtktypes->next; li; li=g_list_next(li))
647 out_printf(out, "%s, ", get_cast(li->data, FALSE));
649 out_printf(out, "gpointer);\n");
651 out_printf(out,"\nstatic void\n"
652 "___marshal_%s (GtkObject * object,\n"
653 "\tGtkSignalFunc func,\n"
654 "\tgpointer func_data,\n"
658 if(strcmp(m->gtktypes->data, "NONE")==0) {
659 out_printf(out, "\t___%s rfunc;\n\n"
660 "\trfunc = (___%s)func;\n\n"
661 "\t(*rfunc)((%s *)object", s, s, typebase);
663 const char *retcast = get_cast(m->gtktypes->data, FALSE);
667 "\trfunc = (___%s)func;\n\n"
668 "\tretval = GTK_RETLOC_%s(args[%d]);\n\n"
669 "\t*retval = (*rfunc)((%s *)object",
670 s, retcast, s, (char *)m->gtktypes->data,
671 g_list_length(m->gtktypes)-1, typebase);
673 print_signal_marsal_args(m);
681 out_printf(out,"\n");
683 out_printf(out,"enum {\n");
684 for(li=c->nodes;li;li=g_list_next(li)) {
686 if(n->type == METHOD_NODE) {
687 Method *m = (Method *)n;
688 if(m->method == SIGNAL_LAST_METHOD ||
689 m->method == SIGNAL_FIRST_METHOD) {
690 char *s = g_strdup(m->id);
692 out_printf(out,"\t%s_SIGNAL,\n",s);
697 out_printf(out,"\tLAST_SIGNAL\n};\n\n");
700 out_printf(out,"enum {\n\tARG_0");
701 for(li=c->nodes;li;li=g_list_next(li)) {
703 if(n->type == ARGUMENT_NODE) {
704 Argument *a = (Argument *)n;
705 char *s = g_strdup(a->name);
707 out_printf(out,",\n\tARG_%s",s);
711 out_printf(out, "\n};\n\n");
716 "static guint object_signals[LAST_SIGNAL] = {0};\n\n");
718 out_printf(out, "/* pointer to the class of our parent */\n");
719 out_printf(out, "static %sClass *parent_class = NULL;\n\n",ptypebase);
725 out_printf(out, "guint\n"
726 "%s_get_type (void)\n"
728 "\tstatic guint type = 0;\n\n"
730 "\t\tstatic const GtkTypeInfo info = {\n"
732 "\t\t\tsizeof (%s),\n"
733 "\t\t\tsizeof (%sClass),\n"
734 "\t\t\t(GtkClassInitFunc) %s_class_init,\n"
735 "\t\t\t(GtkObjectInitFunc) %s_init,\n"
736 "\t\t\t/* reserved_1 */ NULL,\n"
737 "\t\t\t/* reserved_2 */ NULL,\n"
738 "\t\t\t(GtkClassInitFunc) NULL,\n"
740 "\t\ttype = gtk_type_unique (%s_get_type(), &info);\n"
744 funcbase,typebase,typebase,typebase,
745 funcbase,funcbase,pfuncbase);
749 add_overrides(Class *c, char *oname, gboolean did_gtk_obj)
755 done = g_hash_table_new(g_str_hash, g_str_equal);
757 s = g_strdup("GtkObject"); /* This was already done */
758 g_hash_table_insert(done, s, s);
760 for(li=c->nodes; li; li=g_list_next(li)) {
763 Method *m = (Method *)n;
764 if(n->type != METHOD_NODE ||
765 m->method != OVERRIDE_METHOD)
768 s = remove_sep(m->otype);
770 if(g_hash_table_lookup(done,s)) {
774 g_hash_table_insert(done,s,s);
776 f = replace_sep(m->otype,'_');
779 out_printf(out,"\t%sClass *%s_class = (%sClass *)%s;\n",
784 g_hash_table_foreach(done,(GHFunc)g_free,NULL);
785 g_hash_table_destroy(done);
789 make_run_signal_flags(Method *m, gboolean last)
803 gs = g_string_new(NULL);
806 g_string_assign(gs, "GTK_RUN_LAST");
808 g_string_assign(gs, "GTK_RUN_FIRST");
810 if(m->scope == PUBLIC_SCOPE)
811 g_string_append(gs, " | GTK_RUN_ACTION");
813 for(li = m->flags; li; li = li->next) {
814 char *flag = li->data;
816 for(i=0;flags[i];i++) {
817 if(strcmp(flags[i],flag)==0)
820 /* if we haven't found it in our list */
823 s = g_strdup_printf("Unknown flag '%s' used, "
824 "perhaps it was misspelled",
826 print_error(TRUE, s, m->line_no);
829 g_string_sprintfa(gs, " | GTK_RUN_%s",flag);
834 g_string_free(gs, FALSE);
841 add_signals(Class *c)
845 out_printf(out,"\n");
846 for(li=c->nodes;li;li=g_list_next(li)) {
848 char *mar, *sig, *flags;
849 gboolean is_none, last = FALSE;
850 Method *m = (Method *)n;
852 if(n->type != METHOD_NODE ||
853 (m->method != SIGNAL_FIRST_METHOD &&
854 m->method != SIGNAL_LAST_METHOD))
857 if(m->method == SIGNAL_FIRST_METHOD)
862 if(g_hash_table_lookup(marsh, m))
863 mar = g_strconcat("___marshal_",
864 (char *)g_hash_table_lookup(marsh,m),
867 mar = g_strdup("gtk_signal_default_marshaller");
869 is_none = (strcmp(m->gtktypes->next->data, "NONE")==0);
871 sig = g_strdup(m->id);
873 flags = make_run_signal_flags(m, last);
874 out_printf(out,"\tobject_signals[%s_SIGNAL] =\n"
875 "\t\tgtk_signal_new (\"%s\",\n"
876 "\t\t\t(GtkSignalRunType)(%s),\n"
877 "\t\t\tgtk_object_class->type,\n"
878 "\t\t\tGTK_SIGNAL_OFFSET (%sClass, %s),\n"
880 "\t\t\tGTK_TYPE_%s, %d",
883 typebase,m->id,mar,(char *)m->gtktypes->data,
884 is_none?0:g_list_length(m->gtktypes->next));
891 for(l=m->gtktypes->next;l;l=g_list_next(l))
892 out_printf(out,",\n\t\t\tGTK_TYPE_%s",
896 out_printf(out,");\n");
898 out_printf(out,"\tgtk_object_class_add_signals (gtk_object_class,\n"
899 "\t\tobject_signals, LAST_SIGNAL);\n\n");
903 set_def_handlers(Class *c, char *oname)
906 gboolean set_line = FALSE;
908 out_printf(out,"\n");
909 for(li=c->nodes;li;li=g_list_next(li)) {
911 Method *m = (Method *)n;
912 if(n->type != METHOD_NODE ||
913 (m->method != SIGNAL_FIRST_METHOD &&
914 m->method != SIGNAL_LAST_METHOD &&
915 m->method != VIRTUAL_METHOD &&
916 m->method != OVERRIDE_METHOD))
919 if(m->line_no > 0 && m->cbuf) {
920 out_addline_infile(out, m->line_no);
922 } else if(set_line) {
923 out_addline_outfile(out);
927 if(m->method == OVERRIDE_METHOD) {
929 s = replace_sep(m->otype, '_');
932 out_printf(out,"\t%s_class->%s = %s_%s;\n",
933 s, m->id, funcbase, m->id);
935 out_printf(out,"\t%s_class->%s = NULL;\n",
939 out_printf(out,"\t%s->%s = ___real_%s_%s;\n",
940 oname, m->id, funcbase, m->id);
942 out_printf(out,"\t%s->%s = NULL;\n",
947 out_addline_outfile(out);
951 make_arguments(Class *c)
962 out_printf(out,"\n");
963 for(li=c->nodes;li;li=g_list_next(li)) {
969 if(n->type != ARGUMENT_NODE)
975 flags = g_string_new("GTK_ARG_READWRITE");
977 flags = g_string_new("GTK_ARG_READABLE");
979 flags = g_string_new("GTK_ARG_WRITABLE");
981 for(l=a->flags;l;l=g_list_next(l)) {
982 char *flag = l->data;
984 if(strcmp(flag,"READWRITE")==0 ||
985 strcmp(flag,"READABLE")==0 ||
986 strcmp(flag,"WRITABLE")==0) {
987 print_error(TRUE,"READWRITE, READABLE and "
988 "WRITABLE argument flags are "
989 "set automatically",a->line_no);
992 for(i=0;argflags[i];i++) {
993 if(strcmp(argflags[i],flag)==0)
996 /* if we haven't found it in our list */
999 s = g_strdup_printf("Unknown flag '%s' used, "
1000 "perhaps it was misspelled",
1002 print_error(TRUE,s,a->line_no);
1005 g_string_sprintfa(flags, " | GTK_ARG_%s",flag);
1008 s = g_strdup(a->name);
1010 out_printf(out,"\tgtk_object_add_arg_type(\"%s::%s\",\n"
1011 "\t\tGTK_TYPE_%s,\n"
1014 typebase, a->name, a->gtktype, flags->str, s);
1016 g_string_free(flags, TRUE);
1020 "\n\tgtk_object_class->set_arg = ___object_set_arg;\n"
1021 "\tgtk_object_class->get_arg = ___object_get_arg;\n");
1025 print_initializer(Method *m, Variable *v)
1029 if(v->initializer == NULL)
1032 if(v->scope == PRIVATE_SCOPE)
1033 root = g_strconcat(((FuncArg *)m->args->data)->name,
1036 root = g_strdup(((FuncArg *)m->args->data)->name);
1038 if(v->initializer_line > 0)
1039 out_addline_infile(out, v->initializer_line);
1041 out_printf(out, "\t%s->%s = %s;\n",
1042 root, v->id, v->initializer);
1044 if(v->initializer_line > 0)
1045 out_addline_outfile(out);
1054 for(li=c->nodes;li;li=g_list_next(li)) {
1057 if(n->type != METHOD_NODE)
1060 if(m->method == INIT_METHOD) {
1062 out_addline_infile(out,m->line_no);
1063 print_method(out, "static ", "\n", "", " ", "\n",
1066 out_addline_outfile(out);
1067 out_printf(out,"{\n");
1069 out_printf(out,"\t%s->_priv = "
1070 "g_new0 (%sPrivate, 1);\n",
1071 ((FuncArg *)m->args->data)->name,
1074 if(initializers > 0) {
1076 for(li = ((Class *)class)->nodes;
1080 if(n->type != VARIABLE_NODE)
1082 print_initializer(m, (Variable *)n);
1085 } else if(m->method == CLASS_INIT_METHOD) {
1087 out_addline_infile(out, m->line_no);
1088 print_method(out, "static ", "\n", "", " ", "\n",
1091 out_addline_outfile(out);
1092 out_printf(out,"{\n");
1096 "\tGtkObjectClass *"
1097 "gtk_object_class = "
1098 "(GtkObjectClass*) %s;\n",
1099 ((FuncArg *)m->args->data)->name);
1103 ((FuncArg *)m->args->data)->name,
1104 (signals>0 || arguments>0));
1106 out_printf(out,"\n\tparent_class = ");
1108 out_printf(out,"(%sClass *)",ptypebase);
1109 out_printf(out,"gtk_type_class (%s_get_type ());\n",
1115 set_def_handlers(c, ((FuncArg *)m->args->data)->name);
1124 out_printf(out," {\n");
1125 out_addline_infile(out,m->ccode_line);
1126 out_printf(out,"%s\n",m->cbuf);
1127 out_addline_outfile(out);
1128 out_printf(out," }\n");
1130 out_printf(out,"return;\n");
1132 out_printf(out,"}\n");
1137 add_getset_arg(Class *c, gboolean is_set)
1140 out_printf(out,"\nstatic void\n"
1141 "___object_%s_arg (GtkObject *object,\n"
1146 "\tself = %s (object);\n\n"
1147 "\tswitch (arg_id) {\n",
1148 is_set?"set":"get",typebase,macrobase);
1150 for(li=c->nodes;li;li=g_list_next(li)) {
1156 if(n->type != ARGUMENT_NODE)
1161 line_no = a->set_line;
1164 line_no = a->get_line;
1168 s = g_strdup(a->name);
1170 out_printf(out, "\tcase ARG_%s:\n", s);
1171 if(is_set && a->atype) {
1172 char *cast = get_type(a->atype, TRUE);
1173 if(no_gnu || for_cpp) {
1174 out_printf(out, "#define ARG "
1175 "((%s)GTK_VALUE_%s(*arg))\n",
1178 out_printf(out, "#ifdef __GNUC__\n");
1179 if(strcmp(a->gtktype, "OBJECT")==0) {
1180 out_printf(out, "#define ARG "
1182 "GTK_VALUE_POINTER(*arg); "
1186 out_printf(out, "#define ARG "
1188 "GTK_VALUE_%s(*arg); "
1192 out_printf(out,"#else /* __GNUC__ */\n");
1193 out_printf(out, "#define ARG "
1194 "((%s)GTK_VALUE_%s(*arg))\n",
1196 out_printf(out,"#endif /* __GNUC__ */\n\n");
1198 out_printf(out, "\t\t{\n");
1200 } else if(!is_set && strcmp(a->gtktype, "OBJECT")==0) {
1202 "#define ARG (GTK_VALUE_POINTER(*arg))\n"
1206 "#define ARG (GTK_VALUE_%s(*arg))\n"
1212 out_addline_infile(out, line_no);
1213 out_printf(out,"%s\n",cbuf);
1215 out_addline_outfile(out);
1216 out_printf(out,"\t\t}\n\t\tbreak;\n"
1219 out_printf(out,"\tdefault:\n\t\tbreak;\n\t}\n}\n");
1223 print_checks(Method *m, FuncArg *fa)
1227 gboolean checked_null = FALSE;
1228 is_void = (strcmp(m->mtype->name, "void")==0 &&
1229 m->mtype->stars == 0);
1231 for(li=fa->checks;li;li=g_list_next(li)) {
1232 Check *ch = li->data;
1234 /* point to the method prot in .gob for failed checks */
1236 out_addline_infile(out,m->line_no);
1238 out_printf(out, "\tg_return_if_fail (");
1240 out_printf(out, "\tg_return_val_if_fail (");
1241 switch(ch->chtype) {
1243 out_printf(out, "%s != NULL", fa->name);
1244 checked_null = TRUE;
1247 s = make_pre_macro(fa->atype->name, "IS");
1249 out_printf(out, "%s (%s)", s, fa->name);
1251 /* if not check null, null may be valid */
1252 out_printf(out, "!(%s) || %s (%s)", fa->name,
1257 out_printf(out,"%s < %s",fa->name,ch->number);
1260 out_printf(out,"%s > %s",fa->name,ch->number);
1263 out_printf(out,"%s <= %s",fa->name,ch->number);
1266 out_printf(out,"%s >= %s",fa->name,ch->number);
1269 out_printf(out,"%s == %s",fa->name,ch->number);
1272 out_printf(out,"%s != %s",fa->name,ch->number);
1276 out_printf(out, ");\n");
1278 out_printf(out, ", (");
1279 print_type(out, m->mtype, TRUE);
1280 out_printf(out, ")%s);\n",
1281 m->onerror?m->onerror:"0");
1287 print_preconditions(Method *m)
1291 for(li=m->args;li;li=g_list_next(li)) {
1292 FuncArg *fa = li->data;
1297 out_addline_outfile(out);
1301 print_destructor(char *self_id, Variable *v)
1305 if(v->destructor == NULL)
1308 if(v->scope == PRIVATE_SCOPE)
1309 root = g_strconcat(self_id, "->_priv", NULL);
1311 root = g_strdup(self_id);
1313 if(v->destructor_simple) {
1314 if(v->destructor_line > 0)
1315 out_addline_infile(out, v->destructor_line);
1317 out_printf(out, "\tif(%s->%s) "
1318 "((*(void (*)(void *))%s)) (%s->%s);\n",
1319 root, v->id, v->destructor, root, v->id);
1321 if(v->destructor_line > 0)
1322 out_addline_outfile(out);
1324 out_printf(out, "#define VAR (%s->%s)\n", root, v->id);
1325 out_printf(out, "\t{\n\t%s *self G_GNUC_UNUSED = %s;\n",
1327 if(v->destructor_line > 0)
1328 out_addline_infile(out, v->destructor_line);
1330 out_printf(out, "\t%s}\n", v->destructor);
1332 if(v->destructor_line > 0)
1333 out_addline_outfile(out);
1334 out_printf(out, "#undef VAR\n");
1340 /* put in code if it's needed */
1342 put_in_gen_code(Method *m)
1344 if(m->method == OVERRIDE_METHOD &&
1345 strcmp(m->id, "finalize")==0) {
1346 if(privates > 0 || destructors > 0) {
1347 out_printf(out,"\t%s *___self = %s (%s);\n",
1348 typebase, macrobase,
1349 ((FuncArg *)m->args->data)->name);
1351 if(destructors > 0) {
1353 for(li = ((Class *)class)->nodes;
1357 if(n->type == VARIABLE_NODE)
1358 print_destructor("___self",
1363 out_printf(out,"\tg_free (___self->_priv);\n"
1364 "\t___self->_priv = NULL;\n",
1366 ((FuncArg *)m->args->data)->name,
1368 ((FuncArg *)m->args->data)->name);
1374 print_method_body(Method *m, int pre)
1376 out_printf(out,"{\n");
1378 print_preconditions(m);
1382 /* Note: the trailing }'s are on one line, this is so
1383 that we get the no return warning correctly and point to
1384 the correct line in the .gob file, yes this is slightly
1385 ugly in the .c file, but that is not supposed to be
1386 human readable anyway. */
1388 out_printf(out, "{\n");
1390 out_addline_infile(out, m->ccode_line);
1391 out_printf(out, "\t%s}", m->cbuf);
1394 out_printf(out, "}\n");
1397 out_addline_outfile(out);
1401 put_signal_args(Method *m)
1405 for(ali = m->gtktypes->next,li=m->args->next;
1407 li=li->next, ali=ali->next) {
1408 FuncArg *fa = li->data;
1409 const char *cast = get_cast(ali->data, FALSE);
1410 /* we should have already proved before that
1411 the we know all the types */
1414 out_printf(out,",\n\t\t(%s)%s",cast,
1420 get_arg_names_for_macro(Method *m)
1424 GString *gs = g_string_new(NULL);
1426 for(li=m->args;li;li=g_list_next(li)) {
1427 FuncArg *arg = li->data;
1428 g_string_sprintfa(gs, "%s___%s", p, arg->name);
1432 g_string_free(gs, FALSE);
1437 put_method(Method *m)
1441 is_void = (strcmp(m->mtype->name,"void")==0 &&
1442 m->mtype->stars == 0);
1443 out_printf(out,"\n");
1444 doc = get_gtk_doc(m->id);
1446 out_printf(out, "%s", doc);
1450 case REGULAR_METHOD:
1452 out_addline_infile(out,m->line_no);
1453 if(m->scope == PRIVATE_SCOPE)
1454 print_method(out,"static ","\n",""," ","\n",
1456 else /* PUBLIC, PROTECTED */
1457 print_method(out, "", "\n", "", " ", "\n",
1459 print_method_body(m, TRUE);
1461 case SIGNAL_FIRST_METHOD:
1462 case SIGNAL_LAST_METHOD:
1464 out_addline_infile(out,m->line_no);
1465 if(m->scope == PRIVATE_SCOPE)
1466 print_method(out,"static ","\n",""," ","\n",
1468 else /* PUBLIC, PROTECTED */
1469 print_method(out,"","\n",""," ","\n",m,FALSE,FALSE);
1470 out_addline_outfile(out);
1471 out_printf(out,"{\n");
1472 s = g_strdup(m->id);
1474 if(strcmp(m->mtype->name,"void")==0 &&
1475 m->mtype->stars==0) {
1476 print_preconditions(m);
1477 if(((FuncArg *)m->args->data)->name)
1478 out_printf(out,"\tgtk_signal_emit (GTK_OBJECT (%s),\n"
1479 "\t\tobject_signals[%s_SIGNAL]",
1480 ((FuncArg *)m->args->data)->name,s);
1482 out_printf(out,");\n}\n");
1484 out_printf(out, "\t");
1485 print_type(out, m->mtype, TRUE);
1486 out_printf(out, "return_val = (");
1487 print_type(out, m->mtype, TRUE);
1489 out_printf(out, ")(%s);\n", m->defreturn);
1491 out_printf(out, ")(%s);\n", m->onerror);
1493 out_printf(out, ")(0);\n");
1494 print_preconditions(m);
1495 out_printf(out,"\tgtk_signal_emit (GTK_OBJECT (%s),\n"
1496 "\t\tobject_signals[%s_SIGNAL]",
1497 ((FuncArg *)m->args->data)->name,s);
1499 out_printf(out,",\n\t\t&return_val);\n"
1500 "\treturn return_val;\n}\n");
1506 out_addline_infile(out,m->line_no);
1507 print_method(out,"static ","\n___real_",""," ","\n",
1509 print_method_body(m,FALSE);
1511 case VIRTUAL_METHOD:
1513 out_addline_infile(out,m->line_no);
1514 if(m->scope==PRIVATE_SCOPE)
1515 print_method(out,"static ","\n",""," ","\n",
1517 else /* PUBLIC, PROTECTED */
1518 print_method(out,"","\n",""," ","\n",m,FALSE,FALSE);
1519 out_addline_outfile(out);
1520 out_printf(out,"{\n"
1521 "\t%sClass *klass;\n",typebase);
1522 print_preconditions(m);
1523 out_printf(out,"\tklass = %s_CLASS(GTK_OBJECT(%s)->klass);\n\n"
1524 "\tif(klass->%s)\n",
1525 macrobase, ((FuncArg *)m->args->data)->name, m->id);
1526 if(strcmp(m->mtype->name,"void")==0 &&
1527 m->mtype->stars==0) {
1529 out_printf(out,"\t\t(*klass->%s)(%s",m->id,
1530 ((FuncArg *)m->args->data)->name);
1531 for(li=m->args->next;li;li=g_list_next(li)) {
1532 FuncArg *fa = li->data;
1533 out_printf(out,",%s",fa->name);
1535 out_printf(out,");\n}\n");
1538 out_printf(out, "\t\treturn (*klass->%s)(%s",m->id,
1539 ((FuncArg *)m->args->data)->name);
1540 for(li=m->args->next;li;li=g_list_next(li)) {
1541 FuncArg *fa = li->data;
1542 out_printf(out,",%s",fa->name);
1544 out_printf(out, ");\n"
1547 print_type(out, m->mtype, TRUE);
1549 out_printf(out, ")(%s);\n}\n", m->defreturn);
1551 out_printf(out, ")(%s);\n}\n", m->onerror);
1553 out_printf(out, ")(0);\n}\n");
1559 out_addline_infile(out,m->line_no);
1560 print_method(out,"static ","\n___real_",""," ","\n",
1562 print_method_body(m,FALSE);
1564 case OVERRIDE_METHOD:
1568 out_addline_infile(out,m->line_no);
1569 print_method(out,"static ","\n",""," ","\n",
1571 s = replace_sep(m->otype,'_');
1573 args = get_arg_names_for_macro(m);
1575 out_printf(out,"#define PARENT_HANDLER(%s) \\\n"
1576 "\t{ if(%s_CLASS(parent_class)->%s) \\\n"
1577 "\t\t(* %s_CLASS(parent_class)->%s)(%s); }\n",
1578 args,s,m->id,s,m->id,args);
1580 out_printf(out,"#define PARENT_HANDLER(%s) \\\n"
1581 "\t((%s_CLASS(parent_class)->%s)? \\\n"
1582 "\t\t(* %s_CLASS(parent_class)->%s)(%s): \\\n"
1584 args,s,m->id,s,m->id,args);
1585 out_printf(out,"(");
1586 print_type(out,m->mtype,TRUE);
1587 out_printf(out,")%s))\n",
1588 m->onerror?m->onerror:"0");
1592 print_method_body(m,TRUE);
1593 out_printf(out,"#undef PARENT_HANDLER\n");
1603 char *outfile,*outfileh,*outfileph;
1606 outfile = g_strconcat(filebase,".c",NULL);
1608 outfile = g_strconcat(filebase,".cc",NULL);
1609 if(no_touch_headers)
1610 outfileh = g_strconcat("#gob#",filebase,".h#gob#",NULL);
1612 outfileh = g_strconcat(filebase, ".h", NULL);
1614 if((privates > 0 || protecteds > 0 || always_private_header) &&
1616 outfileph = g_strconcat(filebase, "-private.h", NULL);
1622 devnull = fopen("/dev/null", "w");
1624 g_error("Cannot open null device");
1630 out = fopen(outfile, "w");
1632 g_error("Cannot open outfile: %s", outfile);
1634 outh = fopen(outfileh, "w");
1636 g_error("Cannot open outfile: %s", outfileh);
1638 outph = fopen(outfileph, "w");
1640 g_error("Cannot open outfile: %s", outfileh);
1646 put_argument_nongnu_wrappers(Class *c)
1653 for(li=c->nodes;li;li=g_list_next(li)) {
1655 Argument *a = (Argument *)n;
1659 if(n->type != ARGUMENT_NODE)
1662 aname = g_strdup(a->name);
1666 cast = get_type(a->atype, TRUE);
1668 cast = g_strdup(get_cast(a->gtktype, TRUE));
1672 out_printf(outh, "#define %s_ARG_%s(arg) \t"
1673 "\"%s\",(%s)(arg)\n",
1674 macrobase, aname, a->name, cast);
1676 out_printf(outh, "#define %s_GET_ARG_%s(arg)\t"
1677 "\"%s\",(%s*)(arg)\n",
1678 macrobase, aname, a->name, cast);
1681 out_printf(outh, "#define %s_ARG_%s(arg) \t"
1683 macrobase, aname, a->name);
1685 out_printf(outh, "#define %s_GET_ARG_%s(arg)\t"
1687 macrobase, aname, a->name);
1695 put_argument_gnu_wrappers(Class *c)
1702 for(li=c->nodes;li;li=g_list_next(li)) {
1704 Argument *a = (Argument *)n;
1707 if(n->type != ARGUMENT_NODE)
1709 s = g_strdup(a->name);
1712 cast = get_type(a->atype,TRUE);
1714 cast = g_strdup(get_cast(a->gtktype, TRUE));
1717 out_printf(outh, "#define %s_ARG_%s(arg) \t"
1718 "\"%s\",({%sz = (arg); z;})\n",
1719 macrobase, s, a->name, cast);
1721 out_printf(outh, "#define %s_GET_ARG_%s(arg)\t"
1722 "\"%s\",({%s*z = (arg); z;})\n",
1723 macrobase, s, a->name, cast);
1726 out_printf(outh, "#define %s_ARG_%s(arg) \t"
1728 macrobase, s, a->name);
1730 out_printf(outh, "#define %s_GET_ARG_%s(arg)\t"
1732 macrobase, s, a->name);
1740 print_ccode_block(CCode *cc)
1743 switch(cc->cctype) {
1745 /* HT code is printed exactly like normal header
1746 code but is printed before */
1749 out_printf(fp, "\n");
1752 /* AT code is printed exactly like normal 'all'
1753 code but is printed before */
1756 out_printf(outph, "\n");
1757 out_printf(outph, "%s\n", cc->cbuf);
1758 out_addline_infile(outph, cc->line_no);
1759 out_addline_outfile(outph);
1761 out_printf(outh, "\n");
1762 out_printf(outh, "%s\n", cc->cbuf);
1764 out_printf(fp, "\n");
1765 out_addline_infile(fp, cc->line_no);
1770 out_printf(fp,"\n");
1771 out_addline_infile(fp, cc->line_no);
1778 out_printf(fp, "\n");
1779 out_addline_infile(fp, cc->line_no);
1782 out_printf(fp, "%s\n", cc->cbuf);
1783 if(cc->cctype == C_CCODE ||
1784 cc->cctype == A_CCODE ||
1785 cc->cctype == AT_CCODE ||
1786 cc->cctype == PH_CCODE)
1787 out_addline_outfile(fp);
1791 print_class_block(Class *c)
1795 gboolean printed_private = FALSE;
1798 out_printf(out, "/* utility types we may need */\n");
1799 if(special_array[SPECIAL_2POINTER])
1800 out_printf(out, "typedef struct { "
1801 "gpointer a; gpointer b; "
1802 "} ___twopointertype;\n");
1803 if(special_array[SPECIAL_3POINTER])
1804 out_printf(out, "typedef struct { "
1805 "gpointer a; gpointer b; "
1807 "} ___threepointertype;\n");
1808 if(special_array[SPECIAL_INT_POINTER])
1809 out_printf(out, "typedef struct { "
1810 "gint a; gpointer b; "
1811 "} ___intpointertype;\n");
1812 out_printf(out, "\n");
1815 out_printf(outh, "\n/*\n"
1816 " * Type checking and casting macros\n"
1818 out_printf(outh,"#define %s\t"
1819 "(%s_get_type())\n",
1820 macrotype,funcbase);
1821 out_printf(outh,"#define %s(obj)\t"
1822 "GTK_CHECK_CAST((obj),%s_get_type(),%s)\n",
1823 macrobase,funcbase,typebase);
1824 out_printf(outh,"#define %s_CLASS(klass)\t"
1825 "GTK_CHECK_CLASS_CAST((klass),%s_get_type(),%sClass)\n",
1826 macrobase,funcbase,typebase);
1827 out_printf(outh,"#define %s(obj)\t"
1828 "GTK_CHECK_TYPE((obj), %s_get_type ())\n\n",
1831 out_printf(out, "/* self casting macros */\n");
1832 out_printf(out, "#define SELF(x) %s(x)\n", macrobase);
1833 out_printf(out, "#define IS_SELF(x) %s(x)\n", macrois);
1834 out_printf(out, "#define SELF_CLASS(x) %s_CLASS(x)\n\n", macrobase);
1837 out_printf(outh, "\n/* Private structure type */\n");
1838 out_printf(outh,"typedef struct _%sPrivate %sPrivate;\n",
1842 out_printf(outh, "\n/*\n"
1843 " * Main object structure\n"
1845 s = replace_sep(c->otype,'_');
1847 out_printf(outh,"#ifndef __TYPEDEF_%s__\n"
1848 "#define __TYPEDEF_%s__\n",s,s);
1850 out_printf(outh,"typedef struct _%s %s;\n"
1851 "#endif\n",typebase,typebase);
1852 out_printf(outh,"struct _%s {\n\t%s __parent__;\n",
1853 typebase,ptypebase);
1854 for(l=c->nodes;l;l=g_list_next(l)) {
1855 static gboolean printed_public = FALSE;
1857 Variable *v = (Variable *)n;
1858 if(n->type == VARIABLE_NODE &&
1859 v->scope == PUBLIC_SCOPE) {
1860 if(!printed_public) {
1861 out_printf(outh,"\t/*< public >*/\n");
1862 printed_public = TRUE;
1864 put_variable((Variable *)n,outh);
1867 /* put protecteds always AFTER publics */
1868 for(l=c->nodes;l;l=g_list_next(l)) {
1870 Variable *v = (Variable *)n;
1871 if(n->type == VARIABLE_NODE &&
1872 v->scope == PROTECTED_SCOPE) {
1873 if(!printed_private) {
1874 out_printf(outh,"\t/*< private >*/\n");
1875 printed_private = TRUE;
1877 put_variable((Variable *)n,outh);
1881 if(!printed_private)
1882 out_printf(outh,"\t/*< private >*/\n");
1883 out_printf(outh,"\t%sPrivate *_priv;\n",typebase);
1885 out_printf(outh,"};\n");
1890 /* if we are to stick this into the private
1891 header, if not stick it directly into the
1898 out_printf(outfp,"struct _%sPrivate {\n",
1900 for(l=c->nodes;l;l=l->next) {
1902 Variable *v = (Variable *)n;
1903 if(n->type == VARIABLE_NODE &&
1904 v->scope == PRIVATE_SCOPE) {
1905 out_addline_infile(outfp,v->line_no);
1906 put_variable(v,outfp);
1909 out_addline_outfile(outfp);
1910 out_printf(outfp,"};\n");
1913 out_printf(outh, "\n/*\n"
1914 " * Class definition\n"
1916 out_printf(outh,"typedef struct _%sClass %sClass;\n",
1919 "struct _%sClass {\n\t%sClass __parent__;\n",
1920 typebase,ptypebase);
1921 for(l=c->nodes;l;l=g_list_next(l)) {
1923 if(n->type == METHOD_NODE)
1924 put_vs_method((Method *)n);
1926 out_printf(outh,"};\n\n");
1928 out_printf(out,"/* here are local prototypes */\n");
1930 out_printf(out,"static void ___object_set_arg "
1931 "(GtkObject *object, GtkArg *arg, "
1933 "static void ___object_get_arg "
1934 "(GtkObject *object, GtkArg *arg, "
1935 "guint arg_id);\n");
1938 out_printf(outh, "\n/*\n"
1939 " * Public methods\n"
1942 out_printf(outh,"guint\t%s_get_type\t(void);\n",funcbase);
1943 for(l=c->nodes;l;l=g_list_next(l)) {
1945 if(n->type == METHOD_NODE) {
1946 put_pub_method((Method *)n);
1947 put_prot_method((Method *)n);
1948 put_priv_method_prot((Method *)n);
1952 /* this idea is less and less apealing to me */
1954 if(!no_signal_connect) {
1956 out_printf(outh, "\n/*\n"
1957 " * Signal connection methods\n"
1961 for(l=c->nodes;l;l=g_list_next(l)) {
1963 if(n->type == METHOD_NODE)
1964 put_signal_connect((Method *)n);
1970 /* argument wrapping macros */
1971 if(arguments>0 && !no_gnu) {
1972 out_printf(outh, "\n/*\n"
1973 " * Argument wrapping macros\n"
1975 out_printf(outh,"#ifdef __GNUC__\n");
1976 put_argument_gnu_wrappers(c);
1977 out_printf(outh,"#else /* __GNUC__ */\n");
1978 put_argument_nongnu_wrappers(c);
1979 out_printf(outh,"#endif /* __GNUC__ */\n\n");
1980 } else if(arguments>0 && no_gnu) {
1981 out_printf(outh, "\n/*\n"
1982 " * Argument wrapping macros\n"
1984 put_argument_nongnu_wrappers(c);
1988 for(l=c->nodes;l;l=g_list_next(l)) {
1990 if(n->type == METHOD_NODE)
1991 add_signal_prots((Method *)n);
1999 if(any_method_to_alias(c)) {
2001 make_method_nongnu_aliases(c);
2003 out_printf(out,"\n#ifdef __GNUC__\n");
2004 make_method_gnu_aliases(c);
2005 out_printf(out,"#else /* __GNUC__ */\n");
2006 make_method_nongnu_aliases(c);
2007 out_printf(out,"#endif /* __GNUC__ */\n\n");
2011 out_printf(out,"/* a macro for creating a new object of our type */\n");
2013 "#define GET_NEW ((%s *)gtk_type_new(%s_get_type()))\n\n",
2014 typebase, funcbase);
2019 add_getset_arg(c, TRUE);
2020 add_getset_arg(c, FALSE);
2023 for(l=c->nodes;l;l=g_list_next(l)) {
2025 if(n->type == METHOD_NODE)
2026 put_method((Method *)n);
2029 add_bad_hack_to_avoid_unused_warnings(c);
2033 print_version_macros(void)
2035 int major=0, minor=0, pl=0;
2036 sscanf(VERSION, "%d.%d.%d", &major, &minor, &pl);
2038 out_printf(out, "#define GOB_VERSION_MAJOR %d\n", major);
2039 out_printf(out, "#define GOB_VERSION_MINOR %d\n", minor);
2040 out_printf(out, "#define GOB_VERSION_PATCHLEVEL %d\n\n", pl);
2044 print_file_comments(void)
2048 out_printf(outh, "/* Generated by GOB (v%s)"
2049 " (do not edit directly) */\n\n", VERSION);
2051 out_printf(outph, "/* Generated by GOB (v%s)"
2052 " (do not edit directly) */\n\n", VERSION);
2053 out_printf(out, "/* Generated by GOB (v%s) on %s"
2054 " (do not edit directly) */\n\n",
2055 VERSION, ctime(&curtime));
2059 print_includes(void)
2061 gboolean found_header;
2064 p = g_strconcat(filebase, ".h", NULL);
2065 found_header = TRUE;
2066 if(!g_list_find_custom(include_files, p, (GCompareFunc)strcmp)) {
2067 out_printf(out, "#include \"%s.h\"\n\n", filebase);
2068 found_header = FALSE;
2072 /* if we are creating a private header see if it was included */
2074 p = g_strconcat(filebase, "-private.h", NULL);
2075 if(!g_list_find_custom(include_files, p, (GCompareFunc)strcmp)) {
2076 out_printf(out,"#include \"%s-private.h\"\n\n",
2080 "Implicit private header include "
2082 "\tsource file, while public "
2083 "header is at a custom location, "
2085 "\texplicitly include "
2086 "the private header below the "
2094 print_header_prefixes(void)
2098 p = replace_sep(((Class *)class)->otype, '_');
2100 out_printf(outh, "#ifndef __%s_H__\n#define __%s_H__\n\n", p, p);
2102 out_printf(outph, "#ifndef __%s_PRIVATE_H__\n"
2103 "#define __%s_PRIVATE_H__\n\n"
2104 "#include \"%s.h\"\n\n", p, p, filebase);
2108 out_printf(outh, "#ifdef __cplusplus\n"
2110 "#endif /* __cplusplus */\n\n");
2112 out_printf(outph, "#ifdef __cplusplus\n"
2114 "#endif /* __cplusplus */\n\n");
2119 print_header_postfixes(void)
2122 out_printf(outh, "\n#ifdef __cplusplus\n"
2124 "#endif /* __cplusplus */\n");
2125 out_printf(outh, "\n#endif\n");
2128 out_printf(outph, "\n#ifdef __cplusplus\n"
2130 "#endif /* __cplusplus */\n");
2131 out_printf(outph, "\n#endif\n");
2140 /* print the AT_CCODE blocks */
2141 for(li=nodes;li;li=g_list_next(li)) {
2142 Node *node = li->data;
2143 if(node->type == CCODE_NODE) {
2144 CCode *cc = (CCode *)node;
2145 if(cc->cctype==AT_CCODE)
2146 print_ccode_block((CCode *)node);
2152 print_header_top(void)
2156 /* mandatory include */
2157 out_printf(outh,"#include <gtk/gtk.h>\n\n");
2159 /* print the HT_CCODE blocks */
2160 for(li=nodes;li;li=g_list_next(li)) {
2161 Node *node = li->data;
2162 if(node->type == CCODE_NODE) {
2163 CCode *cc = (CCode *)node;
2164 if(cc->cctype==HT_CCODE)
2165 print_ccode_block((CCode *)node);
2171 generate_outfiles(void)
2175 print_file_comments();
2181 print_header_prefixes();
2183 print_version_macros();
2187 for(li=nodes;li;li=g_list_next(li)) {
2188 Node *node = li->data;
2189 if(node->type == CCODE_NODE) {
2190 CCode *cc = (CCode *)node;
2191 if(cc->cctype!=HT_CCODE)
2192 print_ccode_block((CCode *)node);
2193 } else if(node->type == CLASS_NODE) {
2194 print_class_block((Class *)node);
2196 g_assert_not_reached();
2199 print_header_postfixes();
2205 fprintf(stderr,"Gob version %s\n\n",VERSION);
2206 fprintf(stderr,"Options:\n"
2207 "\t--help,-h,-? Display this help\n"
2208 "\t--version Display version\n"
2209 "\t--exit-on-warn,-w Exit with an error on warnings\n"
2210 "\t--no-exit-on-warn Don't exit on warnings [default]\n"
2211 "\t--for-cpp Create C++ files\n"
2212 "\t--no-extern-c Never print extern \"C\" into the "
2214 "\t--no-gnu Never use GNU extentions\n"
2215 "\t--no-touch-headers Don't touch headers unless they "
2217 "\t--always-private-header Always create a private header "
2219 "\t even if it would be empty\n"
2220 "\t--no-private-header Don't create a private header, "
2222 "\t structure and protected "
2223 "prototypes inside c file\n"
2224 "\t--no-write,-n Don't write output files, just "
2226 "\t--no-lines Don't print '#line' to output\n");
2230 parse_options(int argc, char *argv[])
2233 int got_file = FALSE;
2234 int no_opts = FALSE;
2238 for(i=1;i<argc;i++) {
2239 if(no_opts || argv[i][0]!='-') {
2242 fprintf(stderr, "Specify only one file!\n");
2248 } else if(strcmp(argv[i],"--help")==0) {
2251 } else if(strcmp(argv[i],"--version")==0) {
2252 fprintf(stderr, "Gob version %s\n", VERSION);
2254 } else if(strcmp(argv[i], "--exit-on-warn")==0) {
2255 exit_on_warn = TRUE;
2256 } else if(strcmp(argv[i], "--no-exit-on-warn")==0) {
2257 exit_on_warn = FALSE;
2258 } else if(strcmp(argv[i], "--for-cpp")==0) {
2260 } else if(strcmp(argv[i], "--no-touch-headers")==0) {
2261 no_touch_headers = TRUE;
2262 } else if(strcmp(argv[i], "--always-private-header")==0) {
2263 no_private_header = FALSE;
2264 always_private_header = TRUE;
2265 } else if(strcmp(argv[i], "--no-private-header")==0) {
2266 always_private_header = FALSE;
2267 no_private_header = TRUE;
2268 } else if(strcmp(argv[i], "--no-gnu")==0) {
2270 } else if(strcmp(argv[i], "--no-extern-c")==0) {
2272 } else if(strcmp(argv[i], "--no-write")==0) {
2274 } else if(strcmp(argv[i], "--no-lines")==0) {
2276 } else if(strcmp(argv[i], "--")==0) {
2277 /*further arguments are files*/
2279 } else if(strncmp(argv[i], "--",2)==0) {
2280 /*unknown long option*/
2281 fprintf(stderr, "Unknown option '%s'!\n", argv[i]);
2285 /*by now we know we have a string starting with
2286 - which is a short option string*/
2287 char *p = argv[i]+1;
2288 for(p=argv[i]+1; *p; p++) {
2302 "Unknown option '%c'!\n", *p);
2311 /* this is a somewhat ugly hack, but it appears to work */
2313 compare_and_move_header(void)
2315 char *hfnew = g_strconcat("#gob#", filebase, ".h#gob#", NULL);
2316 char *hf = g_strconcat(filebase, ".h", NULL);
2318 if(stat(hf,&s)==0) {
2320 s = g_strdup_printf("cmp '%s' '%s' > /dev/null", hf, hfnew);
2322 if(unlink(hfnew)!=0)
2324 "Can't remove new header file", 0);
2332 print_error(FALSE, "Can't remove old header file", 0);
2334 if(rename(hfnew,hf)!=0)
2335 print_error(FALSE, "Can't rename new header file", 0);
2341 main(int argc, char *argv[])
2343 parse_options(argc, argv);
2346 yyin = fopen(filename, "r");
2348 fprintf(stderr, "Error: can't open file '%s'\n",
2357 g_error("Parsing errors, quitting");
2359 print_error(FALSE, " no class defined", 0);
2362 exit_on_error = FALSE;
2364 signals = count_signals((Class *)class);
2365 arguments = count_arguments((Class *)class);
2366 overrides = count_overrides((Class *)class);
2367 privates = count_privates((Class *)class);
2368 protecteds = count_protecteds((Class *)class);
2369 destructors = count_destructors((Class *)class);
2370 initializers = count_initializers((Class *)class);
2373 make_inits((Class *)class);
2375 make_finalize((Class *)class);
2376 check_bad_symbols((Class *)class);
2377 check_duplicate_symbols((Class *)class);
2378 check_duplicate_signals_args((Class *)class);
2379 check_public_new((Class *)class);
2380 check_vararg((Class *)class);
2381 check_firstarg((Class *)class);
2382 check_nonvoidempty((Class *)class);
2383 check_signal_args((Class *)class);
2384 check_argument_types((Class *)class);
2386 exit_on_error = TRUE;
2391 any_special = setup_special_array((Class *)class, special_array);
2395 generate_outfiles();
2406 if(no_touch_headers && !no_write)
2407 compare_and_move_header();