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
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, 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, 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 for(li=m->gtktypes->next;li;li=g_list_next(li))
646 out_printf(out, "%s, ", get_cast(li->data, FALSE));
647 out_printf(out,"gpointer);\n");
649 out_printf(out,"\nstatic void\n"
650 "___marshal_%s (GtkObject * object,\n"
651 "\tGtkSignalFunc func,\n"
652 "\tgpointer func_data,\n"
656 if(strcmp(m->gtktypes->data,"NONE")==0) {
657 out_printf(out, "\t___%s rfunc;\n\n"
658 "\trfunc = (___%s)func;\n\n"
659 "\t(*rfunc)((%s *)object",s,s,typebase);
661 out_printf(out, "\t___%s rfunc;\n\t",s);
662 print_type(out,m->mtype,TRUE);
663 out_printf(out, " *retval;\n\n"
664 "\trfunc = (___%s)func;\n\n"
665 "\tretval = GTK_RETLOC_%s(args[%d]);\n\n"
666 "\t*retval = (*rfunc)((%s *)object",
667 s,(char *)m->gtktypes->data,
668 g_list_length(m->gtktypes)-1,typebase);
670 print_signal_marsal_args(m);
678 out_printf(out,"\n");
680 out_printf(out,"enum {\n");
681 for(li=c->nodes;li;li=g_list_next(li)) {
683 if(n->type == METHOD_NODE) {
684 Method *m = (Method *)n;
685 if(m->method == SIGNAL_LAST_METHOD ||
686 m->method == SIGNAL_FIRST_METHOD) {
687 char *s = g_strdup(m->id);
689 out_printf(out,"\t%s_SIGNAL,\n",s);
694 out_printf(out,"\tLAST_SIGNAL\n};\n\n");
697 out_printf(out,"enum {\n\tARG_0");
698 for(li=c->nodes;li;li=g_list_next(li)) {
700 if(n->type == ARGUMENT_NODE) {
701 Argument *a = (Argument *)n;
702 char *s = g_strdup(a->name);
704 out_printf(out,",\n\tARG_%s",s);
708 out_printf(out, "\n};\n\n");
713 "static guint object_signals[LAST_SIGNAL] = {0};\n\n");
715 out_printf(out, "/* pointer to the class of our parent */\n");
716 out_printf(out, "static %sClass *parent_class = NULL;\n\n",ptypebase);
722 out_printf(out, "guint\n"
723 "%s_get_type (void)\n"
725 "\tstatic guint type = 0;\n\n"
727 "\t\tstatic const GtkTypeInfo info = {\n"
729 "\t\t\tsizeof (%s),\n"
730 "\t\t\tsizeof (%sClass),\n"
731 "\t\t\t(GtkClassInitFunc) %s_class_init,\n"
732 "\t\t\t(GtkObjectInitFunc) %s_init,\n"
733 "\t\t\t/* reserved_1 */ NULL,\n"
734 "\t\t\t/* reserved_2 */ NULL,\n"
735 "\t\t\t(GtkClassInitFunc) NULL,\n"
737 "\t\ttype = gtk_type_unique (%s_get_type(), &info);\n"
741 funcbase,typebase,typebase,typebase,
742 funcbase,funcbase,pfuncbase);
746 add_overrides(Class *c, char *oname, gboolean did_gtk_obj)
752 done = g_hash_table_new(g_str_hash, g_str_equal);
754 s = g_strdup("GtkObject"); /* This was already done */
755 g_hash_table_insert(done, s, s);
757 for(li=c->nodes; li; li=g_list_next(li)) {
760 Method *m = (Method *)n;
761 if(n->type != METHOD_NODE ||
762 m->method != OVERRIDE_METHOD)
765 s = remove_sep(m->otype);
767 if(g_hash_table_lookup(done,s)) {
771 g_hash_table_insert(done,s,s);
773 f = replace_sep(m->otype,'_');
776 out_printf(out,"\t%sClass *%s_class = (%sClass *)%s;\n",
781 g_hash_table_foreach(done,(GHFunc)g_free,NULL);
782 g_hash_table_destroy(done);
786 make_run_signal_flags(Method *m, gboolean last)
800 gs = g_string_new(NULL);
803 g_string_assign(gs, "GTK_RUN_LAST");
805 g_string_assign(gs, "GTK_RUN_FIRST");
807 if(m->scope == PUBLIC_SCOPE)
808 g_string_append(gs, " | GTK_RUN_ACTION");
810 for(li = m->flags; li; li = li->next) {
811 char *flag = li->data;
813 for(i=0;flags[i];i++) {
814 if(strcmp(flags[i],flag)==0)
817 /* if we haven't found it in our list */
820 s = g_strdup_printf("Unknown flag '%s' used, "
821 "perhaps it was misspelled",
823 print_error(TRUE, s, m->line_no);
826 g_string_sprintfa(gs, " | GTK_RUN_%s",flag);
831 g_string_free(gs, FALSE);
838 add_signals(Class *c)
842 out_printf(out,"\n");
843 for(li=c->nodes;li;li=g_list_next(li)) {
845 char *mar, *sig, *flags;
846 gboolean is_none, last = FALSE;
847 Method *m = (Method *)n;
849 if(n->type != METHOD_NODE ||
850 (m->method != SIGNAL_FIRST_METHOD &&
851 m->method != SIGNAL_LAST_METHOD))
854 if(m->method == SIGNAL_FIRST_METHOD)
859 if(g_hash_table_lookup(marsh, m))
860 mar = g_strconcat("___marshal_",
861 (char *)g_hash_table_lookup(marsh,m),
864 mar = g_strdup("gtk_signal_default_marshaller");
866 is_none = (strcmp(m->gtktypes->next->data, "NONE")==0);
868 sig = g_strdup(m->id);
870 flags = make_run_signal_flags(m, last);
871 out_printf(out,"\tobject_signals[%s_SIGNAL] =\n"
872 "\t\tgtk_signal_new (\"%s\",\n"
873 "\t\t\t(GtkSignalRunType)(%s),\n"
874 "\t\t\tgtk_object_class->type,\n"
875 "\t\t\tGTK_SIGNAL_OFFSET (%sClass, %s),\n"
877 "\t\t\tGTK_TYPE_%s, %d",
880 typebase,m->id,mar,(char *)m->gtktypes->data,
881 is_none?0:g_list_length(m->gtktypes->next));
888 for(l=m->gtktypes->next;l;l=g_list_next(l))
889 out_printf(out,",\n\t\t\tGTK_TYPE_%s",
893 out_printf(out,");\n");
895 out_printf(out,"\tgtk_object_class_add_signals (gtk_object_class,\n"
896 "\t\tobject_signals, LAST_SIGNAL);\n\n");
900 set_def_handlers(Class *c, char *oname)
903 gboolean set_line = FALSE;
905 out_printf(out,"\n");
906 for(li=c->nodes;li;li=g_list_next(li)) {
908 Method *m = (Method *)n;
909 if(n->type != METHOD_NODE ||
910 (m->method != SIGNAL_FIRST_METHOD &&
911 m->method != SIGNAL_LAST_METHOD &&
912 m->method != VIRTUAL_METHOD &&
913 m->method != OVERRIDE_METHOD))
916 if(m->line_no > 0 && m->cbuf) {
917 out_addline_infile(out, m->line_no);
919 } else if(set_line) {
920 out_addline_outfile(out);
924 if(m->method == OVERRIDE_METHOD) {
926 s = replace_sep(m->otype, '_');
929 out_printf(out,"\t%s_class->%s = %s_%s;\n",
930 s, m->id, funcbase, m->id);
932 out_printf(out,"\t%s_class->%s = NULL;\n",
936 out_printf(out,"\t%s->%s = ___real_%s_%s;\n",
937 oname, m->id, funcbase, m->id);
939 out_printf(out,"\t%s->%s = NULL;\n",
944 out_addline_outfile(out);
948 make_arguments(Class *c)
959 out_printf(out,"\n");
960 for(li=c->nodes;li;li=g_list_next(li)) {
966 if(n->type != ARGUMENT_NODE)
972 flags = g_string_new("GTK_ARG_READWRITE");
974 flags = g_string_new("GTK_ARG_READABLE");
976 flags = g_string_new("GTK_ARG_WRITABLE");
978 for(l=a->flags;l;l=g_list_next(l)) {
979 char *flag = l->data;
981 if(strcmp(flag,"READWRITE")==0 ||
982 strcmp(flag,"READABLE")==0 ||
983 strcmp(flag,"WRITABLE")==0) {
984 print_error(TRUE,"READWRITE, READABLE and "
985 "WRITABLE argument flags are "
986 "set automatically",a->line_no);
989 for(i=0;argflags[i];i++) {
990 if(strcmp(argflags[i],flag)==0)
993 /* if we haven't found it in our list */
996 s = g_strdup_printf("Unknown flag '%s' used, "
997 "perhaps it was misspelled",
999 print_error(TRUE,s,a->line_no);
1002 g_string_sprintfa(flags, " | GTK_ARG_%s",flag);
1005 s = g_strdup(a->name);
1007 out_printf(out,"\tgtk_object_add_arg_type(\"%s::%s\",\n"
1008 "\t\tGTK_TYPE_%s,\n"
1011 typebase, a->name, a->gtktype, flags->str, s);
1013 g_string_free(flags, TRUE);
1017 "\n\tgtk_object_class->set_arg = ___object_set_arg;\n"
1018 "\tgtk_object_class->get_arg = ___object_get_arg;\n");
1022 print_initializer(Method *m, Variable *v)
1026 if(v->initializer == NULL)
1029 if(v->scope == PRIVATE_SCOPE)
1030 root = g_strconcat(((FuncArg *)m->args->data)->name,
1033 root = g_strdup(((FuncArg *)m->args->data)->name);
1035 if(v->initializer_line > 0)
1036 out_addline_infile(out, v->initializer_line);
1038 out_printf(out, "\t%s->%s = %s;\n",
1039 root, v->id, v->initializer);
1041 if(v->initializer_line > 0)
1042 out_addline_outfile(out);
1051 for(li=c->nodes;li;li=g_list_next(li)) {
1054 if(n->type != METHOD_NODE)
1057 if(m->method == INIT_METHOD) {
1059 out_addline_infile(out,m->line_no);
1060 print_method(out, "static ", "\n", "", " ", "\n",
1063 out_addline_outfile(out);
1064 out_printf(out,"{\n");
1066 out_printf(out,"\t%s->_priv = "
1067 "g_new0 (%sPrivate, 1);\n",
1068 ((FuncArg *)m->args->data)->name,
1071 if(initializers > 0) {
1073 for(li = ((Class *)class)->nodes;
1077 if(n->type != VARIABLE_NODE)
1079 print_initializer(m, (Variable *)n);
1082 } else if(m->method == CLASS_INIT_METHOD) {
1084 out_addline_infile(out, m->line_no);
1085 print_method(out, "static ", "\n", "", " ", "\n",
1088 out_addline_outfile(out);
1089 out_printf(out,"{\n");
1093 "\tGtkObjectClass *"
1094 "gtk_object_class = "
1095 "(GtkObjectClass*) %s;\n",
1096 ((FuncArg *)m->args->data)->name);
1100 ((FuncArg *)m->args->data)->name,
1101 (signals>0 || arguments>0));
1103 out_printf(out,"\n\tparent_class = ");
1105 out_printf(out,"(%sClass *)",ptypebase);
1106 out_printf(out,"gtk_type_class (%s_get_type ());\n",
1112 set_def_handlers(c, ((FuncArg *)m->args->data)->name);
1121 out_printf(out," {\n");
1122 out_addline_infile(out,m->ccode_line);
1123 out_printf(out,"%s\n",m->cbuf);
1124 out_addline_outfile(out);
1125 out_printf(out," }\n");
1127 out_printf(out,"return;\n");
1129 out_printf(out,"}\n");
1134 add_getset_arg(Class *c, gboolean is_set)
1137 out_printf(out,"\nstatic void\n"
1138 "___object_%s_arg (GtkObject *object,\n"
1143 "\tself = %s (object);\n\n"
1144 "\tswitch (arg_id) {\n",
1145 is_set?"set":"get",typebase,macrobase);
1147 for(li=c->nodes;li;li=g_list_next(li)) {
1153 if(n->type != ARGUMENT_NODE)
1158 line_no = a->set_line;
1161 line_no = a->get_line;
1165 s = g_strdup(a->name);
1167 if(is_set && a->atype) {
1168 char *cast = get_type(a->atype, TRUE);
1169 out_printf(out, "\tcase ARG_%s:\n", s);
1170 if(no_gnu || for_cpp) {
1171 out_printf(out, "#define ARG "
1172 "((%s)GTK_VALUE_%s(*arg))\n",
1175 out_printf(out, "#ifdef __GNUC__\n");
1176 out_printf(out, "#define ARG "
1177 "({%s foo = GTK_VALUE_%s(*arg); "
1180 out_printf(out,"#else /* __GNUC__ */\n");
1181 out_printf(out, "#define ARG "
1182 "((%s)GTK_VALUE_%s(*arg))\n",
1184 out_printf(out,"#endif /* __GNUC__ */\n\n");
1186 out_printf(out, "\t\t{\n");
1189 out_printf(out, "\tcase ARG_%s:\n"
1190 "#define ARG (GTK_VALUE_%s(*arg))\n"
1196 out_addline_infile(out, line_no);
1197 out_printf(out,"%s\n",cbuf);
1199 out_addline_outfile(out);
1200 out_printf(out,"\t\t}\n\t\tbreak;\n"
1203 out_printf(out,"\tdefault:\n\t\tbreak;\n\t}\n}\n");
1207 print_checks(Method *m, FuncArg *fa)
1211 gboolean checked_null = FALSE;
1212 is_void = (strcmp(m->mtype->name,"void")==0 &&
1213 m->mtype->stars == 0);
1215 for(li=fa->checks;li;li=g_list_next(li)) {
1216 Check *ch = li->data;
1218 /* point to the method prot in .gob for failed checks */
1220 out_addline_infile(out,m->line_no);
1222 out_printf(out,"\tg_return_if_fail (");
1224 out_printf(out,"\tg_return_val_if_fail (");
1225 switch(ch->chtype) {
1227 out_printf(out,"%s != NULL",fa->name);
1228 checked_null = TRUE;
1231 s = make_pre_macro(fa->atype->name,"IS");
1233 out_printf(out,"%s (%s)",s,fa->name);
1235 /* if not check null, null may be valid */
1236 out_printf(out,"!(%s) || %s (%s)",fa->name,s,
1241 out_printf(out,"%s < %s",fa->name,ch->number);
1244 out_printf(out,"%s > %s",fa->name,ch->number);
1247 out_printf(out,"%s <= %s",fa->name,ch->number);
1250 out_printf(out,"%s >= %s",fa->name,ch->number);
1253 out_printf(out,"%s == %s",fa->name,ch->number);
1256 out_printf(out,"%s != %s",fa->name,ch->number);
1260 out_printf(out, ");\n");
1262 out_printf(out, ", (");
1263 print_type(out, m->mtype, TRUE);
1264 out_printf(out, ")%s);\n",
1265 m->onerror?m->onerror:"0");
1271 print_preconditions(Method *m)
1275 for(li=m->args;li;li=g_list_next(li)) {
1276 FuncArg *fa = li->data;
1281 out_addline_outfile(out);
1285 print_destructor(char *self_id, Variable *v)
1289 if(v->destructor == NULL)
1292 if(v->scope == PRIVATE_SCOPE)
1293 root = g_strconcat(self_id, "->_priv", NULL);
1295 root = g_strdup(self_id);
1297 if(v->destructor_simple) {
1298 if(v->destructor_line > 0)
1299 out_addline_infile(out, v->destructor_line);
1301 out_printf(out, "\tif(%s->%s) "
1302 "((*(void (*)(void *))%s)) (%s->%s);\n",
1303 root, v->id, v->destructor, root, v->id);
1305 if(v->destructor_line > 0)
1306 out_addline_outfile(out);
1308 out_printf(out, "#define VAR (%s->%s)\n", root, v->id);
1309 out_printf(out, "\t{\n\t%s *self G_GNUC_UNUSED = %s;\n",
1311 if(v->destructor_line > 0)
1312 out_addline_infile(out, v->destructor_line);
1314 out_printf(out, "\t%s}\n", v->destructor);
1316 if(v->destructor_line > 0)
1317 out_addline_outfile(out);
1318 out_printf(out, "#undef VAR\n");
1324 /* put in code if it's needed */
1326 put_in_gen_code(Method *m)
1328 if(m->method == OVERRIDE_METHOD &&
1329 strcmp(m->id, "finalize")==0) {
1330 if(privates > 0 || destructors > 0) {
1331 out_printf(out,"\t%s *___self = %s (%s);\n",
1332 typebase, macrobase,
1333 ((FuncArg *)m->args->data)->name);
1335 if(destructors > 0) {
1337 for(li = ((Class *)class)->nodes;
1341 if(n->type == VARIABLE_NODE)
1342 print_destructor("___self",
1347 out_printf(out,"\tg_free (___self->_priv);\n"
1348 "\t___self->_priv = NULL;\n",
1350 ((FuncArg *)m->args->data)->name,
1352 ((FuncArg *)m->args->data)->name);
1358 print_method_body(Method *m, int pre)
1360 out_printf(out,"{\n");
1362 print_preconditions(m);
1366 /* Note: the trailing }'s are on one line, this is so
1367 that we get the no return warning correctly and point to
1368 the correct line in the .gob file, yes this is slightly
1369 ugly in the .c file, but that is not supposed to be
1370 human readable anyway. */
1372 out_printf(out, "{\n");
1374 out_addline_infile(out, m->ccode_line);
1375 out_printf(out, "\t%s}", m->cbuf);
1378 out_printf(out, "}\n");
1381 out_addline_outfile(out);
1385 put_signal_args(Method *m)
1389 for(ali = m->gtktypes->next,li=m->args->next;
1391 li=li->next, ali=ali->next) {
1392 FuncArg *fa = li->data;
1393 const char *cast = get_cast(ali->data, FALSE);
1394 /* we should have already proved before that
1395 the we know all the types */
1398 out_printf(out,",\n\t\t(%s)%s",cast,
1404 get_arg_names_for_macro(Method *m)
1408 GString *gs = g_string_new(NULL);
1410 for(li=m->args;li;li=g_list_next(li)) {
1411 FuncArg *arg = li->data;
1412 g_string_sprintfa(gs, "%s___%s", p, arg->name);
1416 g_string_free(gs, FALSE);
1421 put_method(Method *m)
1425 is_void = (strcmp(m->mtype->name,"void")==0 &&
1426 m->mtype->stars == 0);
1427 out_printf(out,"\n");
1428 doc = get_gtk_doc(m->id);
1430 out_printf(out, "%s", doc);
1434 case REGULAR_METHOD:
1436 out_addline_infile(out,m->line_no);
1437 if(m->scope == PRIVATE_SCOPE)
1438 print_method(out,"static ","\n",""," ","\n",
1440 else /* PUBLIC, PROTECTED */
1441 print_method(out, "", "\n", "", " ", "\n",
1443 print_method_body(m, TRUE);
1445 case SIGNAL_FIRST_METHOD:
1446 case SIGNAL_LAST_METHOD:
1448 out_addline_infile(out,m->line_no);
1449 if(m->scope == PRIVATE_SCOPE)
1450 print_method(out,"static ","\n",""," ","\n",
1452 else /* PUBLIC, PROTECTED */
1453 print_method(out,"","\n",""," ","\n",m,FALSE,FALSE);
1454 out_addline_outfile(out);
1455 out_printf(out,"{\n");
1456 s = g_strdup(m->id);
1458 if(strcmp(m->mtype->name,"void")==0 &&
1459 m->mtype->stars==0) {
1460 print_preconditions(m);
1461 if(((FuncArg *)m->args->data)->name)
1462 out_printf(out,"\tgtk_signal_emit (GTK_OBJECT (%s),\n"
1463 "\t\tobject_signals[%s_SIGNAL]",
1464 ((FuncArg *)m->args->data)->name,s);
1466 out_printf(out,");\n}\n");
1468 out_printf(out,"\t");
1469 print_type(out,m->mtype,TRUE);
1470 out_printf(out,"return_val;\n");
1471 print_preconditions(m);
1472 out_printf(out,"\tgtk_signal_emit (GTK_OBJECT (%s),\n"
1473 "\t\tobject_signals[%s_SIGNAL]",
1474 ((FuncArg *)m->args->data)->name,s);
1476 out_printf(out,",\n\t\t&return_val);\n"
1477 "\treturn return_val;\n}\n");
1483 out_addline_infile(out,m->line_no);
1484 print_method(out,"static ","\n___real_",""," ","\n",
1486 print_method_body(m,FALSE);
1488 case VIRTUAL_METHOD:
1490 out_addline_infile(out,m->line_no);
1491 if(m->scope==PRIVATE_SCOPE)
1492 print_method(out,"static ","\n",""," ","\n",
1494 else /* PUBLIC, PROTECTED */
1495 print_method(out,"","\n",""," ","\n",m,FALSE,FALSE);
1496 out_addline_outfile(out);
1497 out_printf(out,"{\n"
1498 "\t%sClass *klass;\n",typebase);
1499 print_preconditions(m);
1500 out_printf(out,"\tklass = %s_CLASS(GTK_OBJECT(%s)->klass);\n\n"
1501 "\tif(klass->%s)\n",
1502 macrobase, ((FuncArg *)m->args->data)->name, m->id);
1503 if(strcmp(m->mtype->name,"void")==0 &&
1504 m->mtype->stars==0) {
1506 out_printf(out,"\t\t(*klass->%s)(%s",m->id,
1507 ((FuncArg *)m->args->data)->name);
1508 for(li=m->args->next;li;li=g_list_next(li)) {
1509 FuncArg *fa = li->data;
1510 out_printf(out,",%s",fa->name);
1512 out_printf(out,");\n}\n");
1515 out_printf(out,"\t\treturn (*klass->%s)(%s",m->id,
1516 ((FuncArg *)m->args->data)->name);
1517 for(li=m->args->next;li;li=g_list_next(li)) {
1518 FuncArg *fa = li->data;
1519 out_printf(out,",%s",fa->name);
1521 out_printf(out,");\n"
1524 print_type(out,m->mtype,TRUE);
1525 out_printf(out,")(%s);\n}\n",
1526 m->onerror?m->onerror:"0");
1532 out_addline_infile(out,m->line_no);
1533 print_method(out,"static ","\n___real_",""," ","\n",
1535 print_method_body(m,FALSE);
1537 case OVERRIDE_METHOD:
1541 out_addline_infile(out,m->line_no);
1542 print_method(out,"static ","\n",""," ","\n",
1544 s = replace_sep(m->otype,'_');
1546 args = get_arg_names_for_macro(m);
1548 out_printf(out,"#define PARENT_HANDLER(%s) \\\n"
1549 "\t{ if(%s_CLASS(parent_class)->%s) \\\n"
1550 "\t\t(* %s_CLASS(parent_class)->%s)(%s); }\n",
1551 args,s,m->id,s,m->id,args);
1553 out_printf(out,"#define PARENT_HANDLER(%s) \\\n"
1554 "\t((%s_CLASS(parent_class)->%s)? \\\n"
1555 "\t\t(* %s_CLASS(parent_class)->%s)(%s): \\\n"
1557 args,s,m->id,s,m->id,args);
1558 out_printf(out,"(");
1559 print_type(out,m->mtype,TRUE);
1560 out_printf(out,")%s))\n",
1561 m->onerror?m->onerror:"0");
1565 print_method_body(m,TRUE);
1566 out_printf(out,"#undef PARENT_HANDLER\n");
1576 char *outfile,*outfileh,*outfileph;
1579 outfile = g_strconcat(filebase,".c",NULL);
1581 outfile = g_strconcat(filebase,".cc",NULL);
1582 if(no_touch_headers)
1583 outfileh = g_strconcat("#gob#",filebase,".h#gob#",NULL);
1585 outfileh = g_strconcat(filebase, ".h", NULL);
1587 if((privates > 0 || protecteds > 0 || always_private_header) &&
1589 outfileph = g_strconcat(filebase, "-private.h", NULL);
1595 devnull = fopen("/dev/null", "w");
1597 g_error("Cannot open null device");
1603 out = fopen(outfile, "w");
1605 g_error("Cannot open outfile: %s", outfile);
1607 outh = fopen(outfileh, "w");
1609 g_error("Cannot open outfile: %s", outfileh);
1611 outph = fopen(outfileph, "w");
1613 g_error("Cannot open outfile: %s", outfileh);
1619 put_argument_nongnu_wrappers(Class *c)
1626 for(li=c->nodes;li;li=g_list_next(li)) {
1628 Argument *a = (Argument *)n;
1632 if(n->type != ARGUMENT_NODE)
1635 aname = g_strdup(a->name);
1639 cast = get_type(a->atype, TRUE);
1641 cast = g_strdup(get_cast(a->gtktype, TRUE));
1645 out_printf(outh, "#define %s_ARG_%s(arg) \t"
1646 "\"%s\",(%s)(arg)\n",
1647 macrobase, aname, a->name, cast);
1649 out_printf(outh, "#define %s_GET_ARG_%s(arg)\t"
1650 "\"%s\",(%s*)(arg)\n",
1651 macrobase, aname, a->name, cast);
1654 out_printf(outh, "#define %s_ARG_%s(arg) \t"
1656 macrobase, aname, a->name);
1658 out_printf(outh, "#define %s_GET_ARG_%s(arg)\t"
1660 macrobase, aname, a->name);
1668 put_argument_gnu_wrappers(Class *c)
1675 for(li=c->nodes;li;li=g_list_next(li)) {
1677 Argument *a = (Argument *)n;
1680 if(n->type != ARGUMENT_NODE)
1682 s = g_strdup(a->name);
1685 cast = get_type(a->atype,TRUE);
1687 cast = g_strdup(get_cast(a->gtktype, TRUE));
1690 out_printf(outh, "#define %s_ARG_%s(arg) \t"
1691 "\"%s\",({%sz = (arg); z;})\n",
1692 macrobase, s, a->name, cast);
1694 out_printf(outh, "#define %s_GET_ARG_%s(arg)\t"
1695 "\"%s\",({%s*z = (arg); z;})\n",
1696 macrobase, s, a->name, cast);
1699 out_printf(outh, "#define %s_ARG_%s(arg) \t"
1701 macrobase, s, a->name);
1703 out_printf(outh, "#define %s_GET_ARG_%s(arg)\t"
1705 macrobase, s, a->name);
1713 print_ccode_block(CCode *cc)
1716 switch(cc->cctype) {
1718 /* HT code is printed exactly like normal header
1719 code but is printed before */
1722 out_printf(fp, "\n");
1725 /* AT code is printed exactly like normal 'all'
1726 code but is printed before */
1729 out_printf(outph, "\n");
1730 out_printf(outph, "%s\n", cc->cbuf);
1731 out_addline_infile(outph, cc->line_no);
1732 out_addline_outfile(outph);
1734 out_printf(outh, "\n");
1735 out_printf(outh, "%s\n", cc->cbuf);
1737 out_printf(fp, "\n");
1738 out_addline_infile(fp, cc->line_no);
1743 out_printf(fp,"\n");
1744 out_addline_infile(fp, cc->line_no);
1751 out_printf(fp, "\n");
1752 out_addline_infile(fp, cc->line_no);
1755 out_printf(fp, "%s\n", cc->cbuf);
1756 if(cc->cctype == C_CCODE ||
1757 cc->cctype == A_CCODE ||
1758 cc->cctype == AT_CCODE ||
1759 cc->cctype == PH_CCODE)
1760 out_addline_outfile(fp);
1764 print_class_block(Class *c)
1768 gboolean printed_private = FALSE;
1771 out_printf(out, "/* utility types we may need */\n");
1772 if(special_array[SPECIAL_2POINTER])
1773 out_printf(out, "typedef struct { "
1774 "gpointer a; gpointer b; "
1775 "} ___twopointertype;\n");
1776 if(special_array[SPECIAL_3POINTER])
1777 out_printf(out, "typedef struct { "
1778 "gpointer a; gpointer b; "
1780 "} ___threepointertype;\n");
1781 if(special_array[SPECIAL_INT_POINTER])
1782 out_printf(out, "typedef struct { "
1783 "gint a; gpointer b; "
1784 "} ___intpointertype;\n");
1785 out_printf(out, "\n");
1788 out_printf(outh, "\n/*\n"
1789 " * Type checking and casting macros\n"
1791 out_printf(outh,"#define %s\t"
1792 "(%s_get_type())\n",
1793 macrotype,funcbase);
1794 out_printf(outh,"#define %s(obj)\t"
1795 "GTK_CHECK_CAST((obj),%s_get_type(),%s)\n",
1796 macrobase,funcbase,typebase);
1797 out_printf(outh,"#define %s_CLASS(klass)\t"
1798 "GTK_CHECK_CLASS_CAST((klass),%s_get_type(),%sClass)\n",
1799 macrobase,funcbase,typebase);
1800 out_printf(outh,"#define %s(obj)\t"
1801 "GTK_CHECK_TYPE((obj), %s_get_type ())\n\n",
1804 out_printf(out, "/* self casting macros */\n");
1805 out_printf(out, "#define SELF(x) %s(x)\n", macrobase);
1806 out_printf(out, "#define IS_SELF(x) %s(x)\n", macrois);
1807 out_printf(out, "#define SELF_CLASS(x) %s_CLASS(x)\n\n", macrobase);
1810 out_printf(outh, "\n/* Private structure type */\n");
1811 out_printf(outh,"typedef struct _%sPrivate %sPrivate;\n",
1815 out_printf(outh, "\n/*\n"
1816 " * Main object structure\n"
1818 s = replace_sep(c->otype,'_');
1820 out_printf(outh,"#ifndef __TYPEDEF_%s__\n"
1821 "#define __TYPEDEF_%s__\n",s,s);
1823 out_printf(outh,"typedef struct _%s %s;\n"
1824 "#endif\n",typebase,typebase);
1825 out_printf(outh,"struct _%s {\n\t%s __parent__;\n",
1826 typebase,ptypebase);
1827 for(l=c->nodes;l;l=g_list_next(l)) {
1828 static gboolean printed_public = FALSE;
1830 Variable *v = (Variable *)n;
1831 if(n->type == VARIABLE_NODE &&
1832 v->scope == PUBLIC_SCOPE) {
1833 if(!printed_public) {
1834 out_printf(outh,"\t/*< public >*/\n");
1835 printed_public = TRUE;
1837 put_variable((Variable *)n,outh);
1840 /* put protecteds always AFTER publics */
1841 for(l=c->nodes;l;l=g_list_next(l)) {
1843 Variable *v = (Variable *)n;
1844 if(n->type == VARIABLE_NODE &&
1845 v->scope == PROTECTED_SCOPE) {
1846 if(!printed_private) {
1847 out_printf(outh,"\t/*< private >*/\n");
1848 printed_private = TRUE;
1850 put_variable((Variable *)n,outh);
1854 if(!printed_private)
1855 out_printf(outh,"\t/*< private >*/\n");
1856 out_printf(outh,"\t%sPrivate *_priv;\n",typebase);
1858 out_printf(outh,"};\n");
1863 /* if we are to stick this into the private
1864 header, if not stick it directly into the
1871 out_printf(outfp,"struct _%sPrivate {\n",
1873 for(l=c->nodes;l;l=l->next) {
1875 Variable *v = (Variable *)n;
1876 if(n->type == VARIABLE_NODE &&
1877 v->scope == PRIVATE_SCOPE) {
1878 out_addline_infile(outfp,v->line_no);
1879 put_variable(v,outfp);
1882 out_addline_outfile(outfp);
1883 out_printf(outfp,"};\n");
1886 out_printf(outh, "\n/*\n"
1887 " * Class definition\n"
1889 out_printf(outh,"typedef struct _%sClass %sClass;\n",
1892 "struct _%sClass {\n\t%sClass __parent__;\n",
1893 typebase,ptypebase);
1894 for(l=c->nodes;l;l=g_list_next(l)) {
1896 if(n->type == METHOD_NODE)
1897 put_vs_method((Method *)n);
1899 out_printf(outh,"};\n\n");
1901 out_printf(out,"/* here are local prototypes */\n");
1903 out_printf(out,"static void ___object_set_arg "
1904 "(GtkObject *object, GtkArg *arg, "
1906 "static void ___object_get_arg "
1907 "(GtkObject *object, GtkArg *arg, "
1908 "guint arg_id);\n");
1911 out_printf(outh, "\n/*\n"
1912 " * Public methods\n"
1915 out_printf(outh,"guint\t%s_get_type\t(void);\n",funcbase);
1916 for(l=c->nodes;l;l=g_list_next(l)) {
1918 if(n->type == METHOD_NODE) {
1919 put_pub_method((Method *)n);
1920 put_prot_method((Method *)n);
1921 put_priv_method_prot((Method *)n);
1925 /* this idea is less and less apealing to me */
1927 if(!no_signal_connect) {
1929 out_printf(outh, "\n/*\n"
1930 " * Signal connection methods\n"
1934 for(l=c->nodes;l;l=g_list_next(l)) {
1936 if(n->type == METHOD_NODE)
1937 put_signal_connect((Method *)n);
1943 /* argument wrapping macros */
1944 if(arguments>0 && !no_gnu) {
1945 out_printf(outh, "\n/*\n"
1946 " * Argument wrapping macros\n"
1948 out_printf(outh,"#ifdef __GNUC__\n");
1949 put_argument_gnu_wrappers(c);
1950 out_printf(outh,"#else /* __GNUC__ */\n");
1951 put_argument_nongnu_wrappers(c);
1952 out_printf(outh,"#endif /* __GNUC__ */\n\n");
1953 } else if(arguments>0 && no_gnu) {
1954 out_printf(outh, "\n/*\n"
1955 " * Argument wrapping macros\n"
1957 put_argument_nongnu_wrappers(c);
1961 for(l=c->nodes;l;l=g_list_next(l)) {
1963 if(n->type == METHOD_NODE)
1964 add_signal_prots((Method *)n);
1972 if(any_method_to_alias(c)) {
1974 make_method_nongnu_aliases(c);
1976 out_printf(out,"\n#ifdef __GNUC__\n");
1977 make_method_gnu_aliases(c);
1978 out_printf(out,"#else /* __GNUC__ */\n");
1979 make_method_nongnu_aliases(c);
1980 out_printf(out,"#endif /* __GNUC__ */\n\n");
1984 out_printf(out,"/* a macro for creating a new object of our type */\n");
1986 "#define GET_NEW ((%s *)gtk_type_new(%s_get_type()))\n\n",
1987 typebase, funcbase);
1992 add_getset_arg(c, TRUE);
1993 add_getset_arg(c, FALSE);
1996 for(l=c->nodes;l;l=g_list_next(l)) {
1998 if(n->type == METHOD_NODE)
1999 put_method((Method *)n);
2002 add_bad_hack_to_avoid_unused_warnings(c);
2006 print_version_macros(void)
2008 int major=0, minor=0, pl=0;
2009 sscanf(VERSION, "%d.%d.%d", &major, &minor, &pl);
2011 out_printf(out, "#define GOB_VERSION_MAJOR %d\n", major);
2012 out_printf(out, "#define GOB_VERSION_MINOR %d\n", minor);
2013 out_printf(out, "#define GOB_VERSION_PATCHLEVEL %d\n\n", pl);
2017 print_file_comments(void)
2021 out_printf(outh, "/* Generated by GOB (v%s)"
2022 " (do not edit directly) */\n\n", VERSION);
2024 out_printf(outph, "/* Generated by GOB (v%s)"
2025 " (do not edit directly) */\n\n", VERSION);
2026 out_printf(out, "/* Generated by GOB (v%s) on %s"
2027 " (do not edit directly) */\n\n",
2028 VERSION, ctime(&curtime));
2032 print_includes(void)
2034 gboolean found_header;
2037 p = g_strconcat(filebase, ".h", NULL);
2038 found_header = TRUE;
2039 if(!g_list_find_custom(include_files, p, (GCompareFunc)strcmp)) {
2040 out_printf(out, "#include \"%s.h\"\n\n", filebase);
2041 found_header = FALSE;
2045 /* if we are creating a private header see if it was included */
2047 p = g_strconcat(filebase, "-private.h", NULL);
2048 if(!g_list_find_custom(include_files, p, (GCompareFunc)strcmp)) {
2049 out_printf(out,"#include \"%s-private.h\"\n\n",
2053 "Implicit private header include "
2055 "\tsource file, while public "
2056 "header is at a custom location, "
2058 "\texplicitly include "
2059 "the private header below the "
2067 print_header_prefixes(void)
2071 p = replace_sep(((Class *)class)->otype, '_');
2073 out_printf(outh, "#ifndef __%s_H__\n#define __%s_H__\n\n", p, p);
2075 out_printf(outph, "#ifndef __%s_PRIVATE_H__\n"
2076 "#define __%s_PRIVATE_H__\n\n"
2077 "#include \"%s.h\"\n\n", p, p, filebase);
2081 out_printf(outh, "#ifdef __cplusplus\n"
2083 "#endif /* __cplusplus */\n\n");
2085 out_printf(outph, "#ifdef __cplusplus\n"
2087 "#endif /* __cplusplus */\n\n");
2092 print_header_postfixes(void)
2095 out_printf(outh,"\n#ifdef __cplusplus\n"
2097 "#endif /* __cplusplus */\n");
2098 out_printf(outh,"\n#endif");
2101 out_printf(outph,"\n#ifdef __cplusplus\n"
2103 "#endif /* __cplusplus */\n");
2104 out_printf(outph,"\n#endif");
2113 /* print the AT_CCODE blocks */
2114 for(li=nodes;li;li=g_list_next(li)) {
2115 Node *node = li->data;
2116 if(node->type == CCODE_NODE) {
2117 CCode *cc = (CCode *)node;
2118 if(cc->cctype==AT_CCODE)
2119 print_ccode_block((CCode *)node);
2125 print_header_top(void)
2129 /* mandatory include */
2130 out_printf(outh,"#include <gtk/gtk.h>\n\n");
2132 /* print the HT_CCODE blocks */
2133 for(li=nodes;li;li=g_list_next(li)) {
2134 Node *node = li->data;
2135 if(node->type == CCODE_NODE) {
2136 CCode *cc = (CCode *)node;
2137 if(cc->cctype==HT_CCODE)
2138 print_ccode_block((CCode *)node);
2144 generate_outfiles(void)
2148 print_file_comments();
2154 print_header_prefixes();
2156 print_version_macros();
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);
2166 } else if(node->type == CLASS_NODE) {
2167 print_class_block((Class *)node);
2169 g_assert_not_reached();
2172 print_header_postfixes();
2178 fprintf(stderr,"Gob version %s\n\n",VERSION);
2179 fprintf(stderr,"Options:\n"
2180 "\t--help,-h,-? Display this help\n"
2181 "\t--version Display version\n"
2182 "\t--exit-on-warn,-w Exit with an error on warnings\n"
2183 "\t--no-exit-on-warn Don't exit on warnings [default]\n"
2184 "\t--for-cpp Create C++ files\n"
2185 "\t--no-extern-c Never print extern \"C\" into the "
2187 "\t--no-gnu Never use GNU extentions\n"
2188 "\t--no-touch-headers Don't touch headers unless they "
2190 "\t--always-private-header Always create a private header "
2192 "\t even if it would be empty\n"
2193 "\t--no-private-header Don't create a private header, "
2195 "\t structure and protected "
2196 "prototypes inside c file\n"
2197 "\t--no-write,-n Don't write output files, just "
2199 "\t--no-lines Don't print '#line' to output\n");
2203 parse_options(int argc, char *argv[])
2206 int got_file = FALSE;
2207 int no_opts = FALSE;
2211 for(i=1;i<argc;i++) {
2212 if(no_opts || argv[i][0]!='-') {
2215 fprintf(stderr, "Specify only one file!\n");
2221 } else if(strcmp(argv[i],"--help")==0) {
2224 } else if(strcmp(argv[i],"--version")==0) {
2225 fprintf(stderr, "Gob version %s\n", VERSION);
2227 } else if(strcmp(argv[i], "--exit-on-warn")==0) {
2228 exit_on_warn = TRUE;
2229 } else if(strcmp(argv[i], "--no-exit-on-warn")==0) {
2230 exit_on_warn = FALSE;
2231 } else if(strcmp(argv[i], "--for-cpp")==0) {
2233 } else if(strcmp(argv[i], "--no-touch-headers")==0) {
2234 no_touch_headers = TRUE;
2235 } else if(strcmp(argv[i], "--always-private-header")==0) {
2236 no_private_header = FALSE;
2237 always_private_header = TRUE;
2238 } else if(strcmp(argv[i], "--no-private-header")==0) {
2239 always_private_header = FALSE;
2240 no_private_header = TRUE;
2241 } else if(strcmp(argv[i], "--no-gnu")==0) {
2243 } else if(strcmp(argv[i], "--no-extern-c")==0) {
2245 } else if(strcmp(argv[i], "--no-write")==0) {
2247 } else if(strcmp(argv[i], "--no-lines")==0) {
2249 } else if(strcmp(argv[i], "--")==0) {
2250 /*further arguments are files*/
2252 } else if(strncmp(argv[i], "--",2)==0) {
2253 /*unknown long option*/
2254 fprintf(stderr, "Unknown option '%s'!\n", argv[i]);
2258 /*by now we know we have a string starting with
2259 - which is a short option string*/
2260 char *p = argv[i]+1;
2261 for(p=argv[i]+1; *p; p++) {
2275 "Unknown option '%c'!\n", *p);
2284 /* this is a somewhat ugly hack, but it appears to work */
2286 compare_and_move_header(void)
2288 char *hfnew = g_strconcat("#gob#", filebase, ".h#gob#", NULL);
2289 char *hf = g_strconcat(filebase, ".h", NULL);
2291 if(stat(hf,&s)==0) {
2293 s = g_strdup_printf("cmp '%s' '%s' > /dev/null", hf, hfnew);
2295 if(unlink(hfnew)!=0)
2297 "Can't remove new header file", 0);
2305 print_error(FALSE, "Can't remove old header file", 0);
2307 if(rename(hfnew,hf)!=0)
2308 print_error(FALSE, "Can't rename new header file", 0);
2314 main(int argc, char *argv[])
2316 parse_options(argc, argv);
2319 yyin = fopen(filename, "r");
2321 fprintf(stderr, "Error: can't open file '%s'\n",
2330 g_error("Parsing errors, quitting");
2332 print_error(FALSE, " no class defined", 0);
2335 exit_on_error = FALSE;
2337 signals = count_signals((Class *)class);
2338 arguments = count_arguments((Class *)class);
2339 overrides = count_overrides((Class *)class);
2340 privates = count_privates((Class *)class);
2341 protecteds = count_protecteds((Class *)class);
2342 destructors = count_destructors((Class *)class);
2343 initializers = count_initializers((Class *)class);
2346 make_inits((Class *)class);
2348 make_finalize((Class *)class);
2349 check_bad_symbols((Class *)class);
2350 check_duplicate_symbols((Class *)class);
2351 check_duplicate_signals_args((Class *)class);
2352 check_public_new((Class *)class);
2353 check_vararg((Class *)class);
2354 check_firstarg((Class *)class);
2355 check_nonvoidempty((Class *)class);
2356 check_signal_args((Class *)class);
2357 check_argument_types((Class *)class);
2359 exit_on_error = TRUE;
2364 any_special = setup_special_array((Class *)class, special_array);
2368 generate_outfiles();
2379 if(no_touch_headers && !no_write)
2380 compare_and_move_header();