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,
34 char *filename = "stdin";
44 static char *funcbase;
45 static char *pfuncbase;
46 static char *macrobase;
48 static char *typebase;
49 static char *ptypebase;
51 static int signals = 0;
52 static int arguments = 0;
53 static int overrides = 0;
58 int exit_on_warn = FALSE;
59 int exit_on_error = TRUE;
60 int got_error = FALSE;
63 print_error(int is_warn, char *error,int line)
73 fprintf(stderr,"%s:%d: %s %s\n",filename,line,w,error);
75 fprintf(stderr,"%s: %s %s\n",filename,w,error);
76 if((!is_warn || exit_on_warn) && exit_on_error)
81 remove_sep(char *base)
84 char *s = g_strdup(base);
85 while((p=strchr(s,':')))
91 replace_sep(char *base, char r)
94 char *s = g_strdup(base);
95 while((p=strchr(s,':')))
105 /*separate the namespace part and then replace rest of
108 separns_replace_sep(char *base, char **ns, char **name, char r)
111 char *s = g_strdup(base);
113 if((p=strchr(s,':')) && p!=s) {
120 while((p=strchr(s,':')))
123 *name = g_strdup(s+1);
130 make_is_macro(char *base)
135 separns_replace_sep(base,&s1,&s2,'_');
137 s = g_strconcat(s1,"_IS_",s2,NULL);
139 s = g_strconcat("IS_",s2,NULL);
152 filebase = replace_sep(((Class *)class)->otype,'-');
155 funcbase = replace_sep(((Class *)class)->otype,'_');
158 pfuncbase = replace_sep(((Class *)class)->ptype,'_');
159 g_strdown(pfuncbase);
161 macrobase = replace_sep(((Class *)class)->otype,'_');
164 macrois = make_is_macro(((Class *)class)->otype);
166 typebase = remove_sep(((Class *)class)->otype);
168 ptypebase = remove_sep(((Class *)class)->ptype);
172 def_methods(Class *c)
176 out_printf(out,"\n");
177 for(li=c->nodes;li;li=g_list_next(li)) {
178 Node *node = li->data;
179 if(node->type == METHOD_NODE) {
180 Method *m = (Method *)node;
182 if(m->scope == INIT_METHOD ||
183 m->scope == CLASS_INIT_METHOD ||
184 m->scope == OVERRIDE_METHOD)
187 out_printf(out,"#define %s %s_%s\n",m->id,funcbase,m->id);
190 out_printf(out,"\n");
194 undef_methods(Class *c)
198 out_printf(out,"\n");
199 for(li=c->nodes;li;li=g_list_next(li)) {
200 Node *node = li->data;
201 if(node->type == METHOD_NODE) {
202 Method *m = (Method *)node;
204 if(m->scope == INIT_METHOD ||
205 m->scope == CLASS_INIT_METHOD ||
206 m->scope == OVERRIDE_METHOD)
209 out_printf(out,"#undef %s\n",m->id);
212 out_printf(out,"\n");
216 print_type(FILE *fp, Type *t)
220 s = remove_sep(t->name);
221 out_printf(fp,"%s ",s);
224 for(i=0;i<t->stars;i++)
229 put_variable(Variable *v)
231 out_printf(outh,"\t");
232 if(v->scope == PRIVATE_SCOPE)
233 out_printf(outh,"/* private */ ");
234 print_type(outh,v->vtype);
236 out_printf(outh,"%s;\n",v->id);
240 print_method(FILE *fp, char *typeprefix, char *nameprefix,
241 char *namepostfix,char *postfix, Method *m)
245 out_printf(fp,"%s",typeprefix);
246 print_type(fp,m->mtype);
247 out_printf(fp,"%s%s_%s%s(",
248 nameprefix,funcbase,m->id,namepostfix);
251 for(li=m->args;li;li=g_list_next(li)) {
252 FuncArg *arg = li->data;
253 print_type(fp,arg->atype);
255 out_printf(fp,"%s, ",arg->name);
257 out_printf(fp,"%s",arg->name);
261 out_printf(fp,", ...");
263 out_printf(fp,"void");
265 out_printf(fp,")%s\n",postfix);
269 put_vs_method(Method *m)
271 if(m->scope != SIGNAL_LAST_METHOD &&
272 m->scope != SIGNAL_FIRST_METHOD &&
273 m->scope != PRIVATE_SIGNAL_LAST_METHOD &&
274 m->scope != PRIVATE_SIGNAL_FIRST_METHOD &&
275 m->scope != VIRTUAL_METHOD &&
276 m->scope != PRIVATE_VIRTUAL_METHOD)
279 print_method(outh,"\t","(* ",") ",";",m);
283 put_pub_method(Method *m)
285 if(m->scope == PRIVATE_SCOPE ||
286 m->scope == OVERRIDE_METHOD ||
287 m->scope == INIT_METHOD ||
288 m->scope == CLASS_INIT_METHOD ||
289 m->scope == PRIVATE_SIGNAL_LAST_METHOD ||
290 m->scope == PRIVATE_SIGNAL_FIRST_METHOD ||
291 m->scope == PRIVATE_VIRTUAL_METHOD)
294 print_method(outh,"","\t","\t",";",m);
298 put_priv_method_prot(Method *m)
300 if(m->scope == PUBLIC_SCOPE)
303 if(m->scope == PRIVATE_SIGNAL_LAST_METHOD ||
304 m->scope == PRIVATE_SIGNAL_FIRST_METHOD ||
305 m->scope == PRIVATE_VIRTUAL_METHOD) {
307 print_method(out,"static ","_real_"," ",";",m);
308 print_method(out,"static ",""," ",";",m);
309 } else if(m->scope == SIGNAL_LAST_METHOD ||
310 m->scope == SIGNAL_FIRST_METHOD ||
311 m->scope == VIRTUAL_METHOD) {
314 print_method(out,"static ","_real_"," ",";",m);
316 print_method(out,"static ",""," ",";",m);
321 make_init_args(Class *cl, char *name, int is_class)
328 tn = g_strconcat(cl->otype,":Class",NULL);
330 tn = g_strdup(cl->otype);
332 type = new_type(1,tn);
333 node = new_funcarg((Type *)type,name,NULL);
334 return g_list_prepend(NULL, node);
338 make_inits(Class *cl)
340 int got_class_init = FALSE;
341 int got_init = FALSE;
344 for(li=cl->nodes;li;li=g_list_next(li)) {
346 if(n->type == METHOD_NODE) {
347 Method *m = (Method *)n;
348 if(m->scope == INIT_METHOD) {
350 print_error(FALSE,"init defined more then once",m->line_no);
352 } else if(m->scope == CLASS_INIT_METHOD) {
354 print_error(FALSE,"class_init defined more then once",m->line_no);
355 got_class_init = TRUE;
359 if(!got_class_init) {
360 node = new_method(CLASS_INIT_METHOD,
361 (Type *)new_type(0,g_strdup("void")),
362 NULL,NULL,g_strdup("class_init"),
363 make_init_args(cl,g_strdup("c"),TRUE),
364 NULL, NULL,0,0,FALSE);
365 cl->nodes = g_list_prepend(cl->nodes,node);
368 node = new_method(INIT_METHOD,
369 (Type *)new_type(0,g_strdup("void")),
370 NULL,NULL,g_strdup("init"),
371 make_init_args(cl,g_strdup("o"),FALSE),
372 NULL, NULL,0,0,FALSE);
373 cl->nodes = g_list_prepend(cl->nodes,node);
377 static GHashTable *marsh = NULL;
380 add_signal_prots(Method *m)
386 if(m->scope != SIGNAL_LAST_METHOD &&
387 m->scope != SIGNAL_FIRST_METHOD &&
388 m->scope != PRIVATE_SIGNAL_LAST_METHOD &&
389 m->scope != PRIVATE_SIGNAL_FIRST_METHOD)
393 marsh = g_hash_table_new(NULL,NULL);
395 if(strcmp(m->gtktypes->data,"NONE")==0 &&
396 strcmp(m->gtktypes->next->data,"NONE")==0)
399 s = g_strdup_printf("__Sig%d",sig++);
401 g_hash_table_insert(marsh,m,s);
403 out_printf(out,"\ntypedef ");
404 print_type(out,m->mtype);
406 out_printf(out,"(*%s) (",s);
408 for(li=m->args;li;li=g_list_next(li)) {
409 FuncArg *arg = li->data;
410 print_type(out,arg->atype);
411 out_printf(out,", ");
413 out_printf(out,"gpointer);\n");
415 out_printf(out,"\nstatic void\n"
416 "marshal_%s (GtkObject * object,\n"
417 "\tGtkSignalFunc func,\n"
418 "\tgpointer func_data,\n"
422 if(strcmp(m->gtktypes->data,"NONE")==0) {
424 out_printf(out, "\t%s rfunc;\n\n"
425 "\trfunc = (%s)func;\n\n"
426 "\t(*rfunc)((%s *)object",s,s,typebase);
427 if(strcmp(m->gtktypes->next->data,"NONE")!=0) {
428 for(i=0,li=m->gtktypes->next;li;
429 i++,li=g_list_next(li)) {
430 out_printf(out, ",\n\t\tGTK_VALUE_%s(args[%d])",
434 out_printf(out, ",\n\t\tfunc_data);\n}\n\n");
437 out_printf(out, "\t%s rfunc;\n\t",s);
438 print_type(out,m->mtype);
439 out_printf(out, " *retval;\n\n"
440 "\trfunc = (%s)func;\n\n"
441 "\tretval = GTK_RETLOC_%s(args[%d]);\n\n"
442 "\t*retval = (*rfunc)((%s *)object",
443 s,(char *)m->gtktypes->data,
444 g_list_length(m->gtktypes)-1,typebase);
445 if(strcmp(m->gtktypes->next->data,"NONE")!=0) {
446 for(i=0,li=m->gtktypes->next;li;
447 i++,li=g_list_next(li)) {
448 out_printf(out, ",\n\t\tGTK_VALUE_%s(args[%d])",
452 out_printf(out, ",\n\t\tfunc_data);\n}\n\n");
461 out_printf(out,"\n");
463 out_printf(out,"enum {\n");
464 for(li=c->nodes;li;li=g_list_next(li)) {
466 if(n->type == METHOD_NODE) {
467 Method *m = (Method *)n;
468 if(m->scope == SIGNAL_LAST_METHOD ||
469 m->scope == SIGNAL_FIRST_METHOD ||
470 m->scope == PRIVATE_SIGNAL_LAST_METHOD ||
471 m->scope == PRIVATE_SIGNAL_FIRST_METHOD) {
472 char *s = g_strdup(m->id);
474 out_printf(out,"\t%s_SIGNAL,\n",s);
479 out_printf(out,"\tLAST_SIGNAL\n};\n\n");
482 out_printf(out,"enum {\n\tARG_0,\n");
483 for(li=c->nodes;li;li=g_list_next(li)) {
485 if(n->type == ARGUMENT_NODE) {
486 Argument *a = (Argument *)n;
487 char *s = g_strdup(a->name);
489 out_printf(out,"\tARG_%s,\n",s);
493 out_printf(out, "};\n\n");
498 "static guint object_signals[LAST_SIGNAL] = {0};\n\n");
500 out_printf(out, "static %sClass *parent_class = NULL;\n\n",ptypebase);
506 out_printf(out, "guint\n"
507 "%s_get_type (void)\n"
509 "\tstatic guint type = 0;\n\n"
511 "\t\tstatic const GtkTypeInfo info = {\n"
513 "\t\t\tsizeof (%s),\n"
514 "\t\t\tsizeof (%sClass),\n"
515 "\t\t\t(GtkClassInitFunc) %s_class_init,\n"
516 "\t\t\t(GtkObjectInitFunc) %s_init,\n"
517 "\t\t\t/* reserved_1 */ NULL,\n"
518 "\t\t\t/* reserved_2 */ NULL,\n"
519 "\t\t\t(GtkClassInitFunc) NULL,\n"
521 "\t\ttype = gtk_type_unique (%s_get_type(), &info);\n"
525 funcbase,typebase,typebase,typebase,
526 funcbase,funcbase,pfuncbase);
530 add_overrides(Class *c, char *oname)
536 done = g_hash_table_new(g_str_hash,g_str_equal);
537 s = g_strdup("GtkObject"); /* This was already done */
538 g_hash_table_insert(done,s,s);
539 for(li=c->nodes;li;li=g_list_next(li)) {
543 if(n->type != METHOD_NODE ||
544 ((Method *)n)->scope != OVERRIDE_METHOD)
548 s = remove_sep(m->otype);
550 if(g_hash_table_lookup(done,s)) {
554 g_hash_table_insert(done,s,s);
556 f = replace_sep(m->otype,'_');
559 out_printf(out,"\t%sClass *%s_class = (%sClass *)%s;\n",
564 g_hash_table_foreach(done,(GHFunc)g_free,NULL);
565 g_hash_table_destroy(done);
569 add_signals(Class *c)
573 out_printf(out,"\n");
574 for(li=c->nodes;li;li=g_list_next(li)) {
581 if(n->type != METHOD_NODE ||
582 (((Method *)n)->scope != SIGNAL_FIRST_METHOD &&
583 ((Method *)n)->scope != SIGNAL_LAST_METHOD &&
584 ((Method *)n)->scope != PRIVATE_SIGNAL_FIRST_METHOD &&
585 ((Method *)n)->scope != PRIVATE_SIGNAL_LAST_METHOD))
590 if(m->scope == SIGNAL_FIRST_METHOD ||
591 m->scope == PRIVATE_SIGNAL_FIRST_METHOD)
596 if(g_hash_table_lookup(marsh,m))
597 mar = g_strconcat("marshal_",
598 (char *)g_hash_table_lookup(marsh,m),
601 mar = g_strdup("gtk_signal_default_marshaller");
603 is_none = (strcmp(m->gtktypes->next->data,"NONE")==0);
605 sig = g_strdup(m->id);
607 out_printf(out,"\tobject_signals[%s_SIGNAL] =\n"
608 "\t\tgtk_signal_new (\"%s\",\n"
609 "\t\t\tGTK_RUN_%s,\n"
610 "\t\t\tgtk_object_class->type,\n"
611 "\t\t\tGTK_SIGNAL_OFFSET (%sClass, %s),\n"
613 "\t\t\tGTK_TYPE_%s, %d",
616 typebase,m->id,mar,(char *)m->gtktypes->data,
617 is_none?0:g_list_length(m->gtktypes->next));
623 for(l=m->gtktypes->next;l;l=g_list_next(l))
624 out_printf(out,",\n\t\t\tGTK_TYPE_%s",
628 out_printf(out,");\n");
630 out_printf(out,"\tgtk_object_class_add_signals (gtk_object_class,\n"
631 "\t\tobject_signals, LAST_SIGNAL);\n\n");
635 set_def_handlers(Class *c, char *oname)
639 out_printf(out,"\n");
640 for(li=c->nodes;li;li=g_list_next(li)) {
643 if(n->type != METHOD_NODE ||
644 (((Method *)n)->scope != SIGNAL_FIRST_METHOD &&
645 ((Method *)n)->scope != SIGNAL_LAST_METHOD &&
646 ((Method *)n)->scope != PRIVATE_SIGNAL_FIRST_METHOD &&
647 ((Method *)n)->scope != PRIVATE_SIGNAL_LAST_METHOD &&
648 ((Method *)n)->scope != VIRTUAL_METHOD &&
649 ((Method *)n)->scope != PRIVATE_VIRTUAL_METHOD &&
650 ((Method *)n)->scope != OVERRIDE_METHOD))
655 if(m->scope == OVERRIDE_METHOD) {
657 s = replace_sep(m->otype,'_');
659 out_printf(out,"\t%s_class->%s = %s_%s;\n",
660 s,m->id,funcbase,m->id);
663 out_printf(out,"\t%s->%s = _real_%s_%s;\n",
664 oname,m->id,funcbase,m->id);
666 out_printf(out,"\t%s->%s = NULL;\n",
673 make_arguments(Class *c)
677 out_printf(out,"\n");
678 for(li=c->nodes;li;li=g_list_next(li)) {
684 if(n->type != ARGUMENT_NODE)
690 flags = g_string_new("GTK_ARG_READWRITE");
692 flags = g_string_new("GTK_ARG_READABLE");
694 flags = g_string_new("GTK_ARG_WRITABLE");
696 for(l=a->flags;l;l=g_list_next(l))
697 g_string_sprintfa(flags," | GTK_ARG_%s",(char *)l->data);
699 s = g_strdup(a->name);
701 out_printf(out,"\tgtk_object_add_arg_type(\"%s::%s\",\n"
705 typebase,a->name,a->gtktype,flags->str,s);
707 g_string_free(flags,TRUE);
711 "\n\tgtk_object_class->set_arg = __object_set_arg;\n"
712 "\tgtk_object_class->get_arg = __object_get_arg;\n");
719 for(li=c->nodes;li;li=g_list_next(li)) {
722 if(n->type != METHOD_NODE)
725 if(m->scope == INIT_METHOD) {
727 out_addline_infile(out,m->line_no);
728 print_method(out,"static ","\n"," ","",m);
730 out_addline_outfile(out);
731 out_printf(out,"{\n");
732 } else if(m->scope == CLASS_INIT_METHOD) {
734 out_addline_infile(out,m->line_no);
735 print_method(out,"static ","\n"," ","",m);
737 out_addline_outfile(out);
738 out_printf(out,"{\n");
744 "gtk_object_class = "
745 "(GtkObjectClass*) %s;\n",
746 ((FuncArg *)m->args->data)->name);
750 ((FuncArg *)m->args->data)->name);
752 out_printf(out,"\n\tparent_class = "
753 "gtk_type_class (%s_get_type ());\n",
759 set_def_handlers(c, ((FuncArg *)m->args->data)->name);
767 out_printf(out," {\n");
768 out_addline_infile(out,m->ccode_line);
769 out_printf(out,"%s\n",m->cbuf->str);
770 out_addline_outfile(out);
771 out_printf(out," }\n",m->cbuf->str);
773 out_printf(out,"return;\n");
775 out_printf(out,"}\n");
780 add_getset_arg(Class *c, int is_set)
783 out_printf(out,"\nstatic void\n"
784 "__object_%s_arg (GtkObject *object,\n"
788 "\t%s *self, *this;\n\n"
789 "\tself = this = %s (object);\n\n"
790 "\tswitch (arg_id) {\n",
791 is_set?"set":"get",typebase,macrobase);
793 for(li=c->nodes;li;li=g_list_next(li)) {
799 if(n->type != ARGUMENT_NODE)
804 line_no = a->set_line;
807 line_no = a->get_line;
811 s = g_strdup(a->name);
813 out_printf(out,"\tcase ARG_%s:\n"
814 "#define ARG (GTK_VALUE_%s(*arg))\n"
818 out_addline_infile(out,line_no);
819 out_printf(out,"%s\n",cbuf->str);
820 out_addline_outfile(out);
821 out_printf(out,"\t\t}\n\t\tbreak;\n"
824 out_printf(out,"\tdefault:\n\t\tbreak;\n\t}\n}\n");
828 print_checks(Method *m, FuncArg *fa)
832 is_void = (strcmp(m->mtype->name,"void")==0 &&
833 m->mtype->stars == 0);
835 for(li=fa->checks;li;li=g_list_next(li)) {
836 Check *ch = li->data;
839 out_printf(out,"\tg_return_if_fail (");
841 out_printf(out,"\tg_return_val_if_fail (");
844 out_printf(out,"%s != NULL",fa->name);
847 s = make_is_macro(fa->atype->name);
848 out_printf(out,"%s (%s)",s,fa->name);
852 out_printf(out,"%s < %s",fa->name,ch->number);
855 out_printf(out,"%s > %s",fa->name,ch->number);
858 out_printf(out,"%s <= %s",fa->name,ch->number);
861 out_printf(out,"%s >= %s",fa->name,ch->number);
864 out_printf(out,"%s == %s",fa->name,ch->number);
867 out_printf(out,"%s != %s",fa->name,ch->number);
871 out_printf(out,");\n");
873 out_printf(out,", (");
874 print_type(out,m->mtype);
875 out_printf(out,")%s);\n",
876 m->onerror?m->onerror:"0");
882 print_preconditions(Method *m)
886 for(li=m->args;li;li=g_list_next(li)) {
887 FuncArg *fa = li->data;
894 print_method_body(Method *m, int pre)
896 out_printf(out,"{\n");
898 print_preconditions(m);
899 out_printf(out,"\t{\n");
902 out_addline_infile(out,m->ccode_line);
903 out_printf(out,"\t\t%s\n",m->cbuf->str);
904 out_addline_outfile(out);
907 out_printf(out,"\t}\n");
908 out_printf(out,"}\n");
912 put_method(Method *m)
916 out_printf(out,"\n");
919 out_addline_infile(out,m->line_no);
920 print_method(out,"","\n"," ","",m);
921 print_method_body(m,TRUE);
924 out_addline_infile(out,m->line_no);
925 print_method(out,"static ","\n"," ","",m);
926 print_method_body(m,TRUE);
928 case PRIVATE_SIGNAL_FIRST_METHOD:
929 case PRIVATE_SIGNAL_LAST_METHOD:
931 case SIGNAL_FIRST_METHOD:
932 case SIGNAL_LAST_METHOD:
933 out_addline_infile(out,m->line_no);
934 print_method(out,private?"static ":"","\n"," ","",m);
935 out_addline_outfile(out);
936 out_printf(out,"{\n");
939 if(strcmp(m->mtype->name,"void")==0 &&
940 m->mtype->stars==0) {
942 print_preconditions(m);
943 if(((FuncArg *)m->args->data)->name)
944 out_printf(out,"\tgtk_signal_emit (GTK_OBJECT (%s),\n"
945 "\t\tobject_signals[%s_SIGNAL]",
946 ((FuncArg *)m->args->data)->name,s);
947 for(li=m->args->next;li;li=g_list_next(li)) {
948 FuncArg *fa = li->data;
949 out_printf(out,",\n\t\t%s",fa->name);
951 out_printf(out,");\n}\n");
954 out_printf(out,"\t");
955 print_type(out,m->mtype);
956 out_printf(out,"return_val;\n");
957 print_preconditions(m);
958 out_printf(out,"\tgtk_signal_emit (GTK_OBJECT (%s),\n"
959 "\t\tobject_signals[%s_SIGNAL]",
960 ((FuncArg *)m->args->data)->name,s);
961 for(li=m->args->next;li;li=g_list_next(li)) {
962 FuncArg *fa = li->data;
963 out_printf(out,",\n\t\t%s",fa->name);
965 out_printf(out,",\n\t\t&return_val);\n"
966 "\treturn return_val;\n}\n");
971 out_addline_infile(out,m->line_no);
972 print_method(out,"static ","\n_real_"," ","",m);
973 print_method_body(m,FALSE);
975 case PRIVATE_VIRTUAL_METHOD:
978 out_addline_infile(out,m->line_no);
979 print_method(out,private?"static ":"","\n"," ","",m);
980 out_addline_outfile(out);
982 "\t%sClass *class;\n",typebase);
983 print_preconditions(m);
984 out_printf(out,"\tclass = %s_CLASS(GTK_OBJECT(%s)->klass);\n\n"
986 macrobase, ((FuncArg *)m->args->data)->name, m->id);
987 if(strcmp(m->mtype->name,"void")==0 &&
988 m->mtype->stars==0) {
990 out_printf(out,"\t\t(*class->%s)(%s",m->id,
991 ((FuncArg *)m->args->data)->name);
992 for(li=m->args->next;li;li=g_list_next(li)) {
993 FuncArg *fa = li->data;
994 out_printf(out,",%s",fa->name);
996 out_printf(out,");\n}\n");
999 out_printf(out,"\t\treturn (*class->%s)(%s",m->id,
1000 ((FuncArg *)m->args->data)->name);
1001 for(li=m->args->next;li;li=g_list_next(li)) {
1002 FuncArg *fa = li->data;
1003 out_printf(out,",%s",fa->name);
1005 out_printf(out,");\n"
1008 print_type(out,m->mtype);
1009 out_printf(out,")(%s);\n}\n",
1010 m->onerror?m->onerror:"0");
1015 out_addline_infile(out,m->line_no);
1016 print_method(out,"static ","\n_real_"," ","",m);
1017 print_method_body(m,FALSE);
1019 case OVERRIDE_METHOD:
1020 out_addline_infile(out,m->line_no);
1021 print_method(out,"static ","\n"," ","",m);
1022 print_method_body(m,TRUE);
1030 check_duplicate(Class *c,Node *node,char *id, int line_no)
1033 for(l=c->nodes;l;l=g_list_next(l)) {
1038 if(n->type == METHOD_NODE) {
1039 Method *m = (Method *)n;
1041 nline_no = m->line_no;
1042 } else if(n->type == VARIABLE_NODE) {
1043 Variable *v = (Variable *)n;
1045 nline_no = v->line_no;
1049 line_no>=nline_no ||
1052 s = g_strdup_printf("symbol '%s' redefined, "
1053 "first defined on line %d",
1055 print_error(FALSE,s,nline_no);
1060 check_duplicate_symbols(Class *c)
1063 for(l=c->nodes;l;l=g_list_next(l)) {
1065 if(n->type == METHOD_NODE) {
1066 Method *m = (Method *)n;
1067 check_duplicate(c,n,m->id,m->line_no);
1068 } else if(n->type == VARIABLE_NODE) {
1069 Variable *v = (Variable *)n;
1070 check_duplicate(c,n,v->id,v->line_no);
1076 check_duplicate_named(Class *c,Node *node,char *id, int line_no)
1079 for(l=c->nodes;l;l=g_list_next(l)) {
1084 if(n->type == METHOD_NODE) {
1085 Method *m = (Method *)n;
1086 if(m->scope == SIGNAL_LAST_METHOD ||
1087 m->scope == SIGNAL_FIRST_METHOD ||
1088 m->scope == PRIVATE_SIGNAL_LAST_METHOD ||
1089 m->scope == PRIVATE_SIGNAL_FIRST_METHOD) {
1091 nline_no = m->line_no;
1094 } else if(n->type == ARGUMENT_NODE) {
1095 Argument *a = (Argument *)n;
1097 nline_no = a->line_no;
1101 line_no>=nline_no ||
1104 s = g_strdup_printf("named symbol (argument or signal) '%s' "
1105 "redefined, first defined on line %d",
1107 print_error(FALSE,s,nline_no);
1112 check_duplicate_signals_args(Class *c)
1115 for(l=c->nodes;l;l=g_list_next(l)) {
1117 if(n->type == METHOD_NODE) {
1118 Method *m = (Method *)n;
1119 if(m->scope == SIGNAL_LAST_METHOD ||
1120 m->scope == SIGNAL_FIRST_METHOD ||
1121 m->scope == PRIVATE_SIGNAL_LAST_METHOD ||
1122 m->scope == PRIVATE_SIGNAL_FIRST_METHOD)
1123 check_duplicate_named(c,n,m->id,m->line_no);
1124 } else if(n->type == ARGUMENT_NODE) {
1125 Argument *a = (Argument *)n;
1126 check_duplicate_named(c,n,a->name,a->line_no);
1132 check_public_new(Class *c)
1135 for(l=c->nodes;l;l=g_list_next(l)) {
1137 if(n->type == METHOD_NODE) {
1138 Method *m = (Method *)n;
1139 if(m->scope!=PUBLIC_SCOPE &&
1140 strcmp(m->id,"new")==0)
1142 "'new' should be a public method",
1149 check_vararg(Class *c)
1152 for(l=c->nodes;l;l=g_list_next(l)) {
1154 if(n->type == METHOD_NODE) {
1155 Method *m = (Method *)n;
1158 if(m->scope == OVERRIDE_METHOD ||
1159 m->scope == SIGNAL_LAST_METHOD ||
1160 m->scope == SIGNAL_FIRST_METHOD ||
1161 m->scope == PRIVATE_SIGNAL_LAST_METHOD ||
1162 m->scope == PRIVATE_SIGNAL_FIRST_METHOD ||
1163 m->scope == VIRTUAL_METHOD ||
1164 m->scope == PRIVATE_VIRTUAL_METHOD) {
1166 "signals, overrides and virtuals, "
1167 "can't have variable argument "
1176 count_signals(Class *c)
1180 for(l=c->nodes;l;l=g_list_next(l)) {
1182 if(n->type == METHOD_NODE) {
1183 Method *m = (Method *)n;
1184 if(m->scope == SIGNAL_LAST_METHOD ||
1185 m->scope == SIGNAL_FIRST_METHOD ||
1186 m->scope == PRIVATE_SIGNAL_LAST_METHOD ||
1187 m->scope == PRIVATE_SIGNAL_FIRST_METHOD)
1195 count_arguments(Class *c)
1200 for(li=c->nodes;li;li=g_list_next(li)) {
1202 if(n->type == ARGUMENT_NODE)
1209 count_overrides(Class *c)
1213 for(l=c->nodes;l;l=g_list_next(l)) {
1215 if(n->type == METHOD_NODE) {
1216 Method *m = (Method *)n;
1217 if(m->scope == OVERRIDE_METHOD)
1228 char *outfile,*outfileh;
1230 outfile = g_strconcat(filebase,".c",NULL);
1231 outfileh = g_strconcat(filebase,".h",NULL);
1233 out = fopen(outfile,"w");
1235 g_error("Cannot open outfile: %s",outfile);
1237 outh = fopen(outfileh,"w");
1239 g_error("Cannot open outfile: %s",outfileh);
1244 generate_outfiles(void)
1251 out_printf(outh,"/* Generated by GOB (v%s) on %s"
1252 " (do not edit directly) */\n\n",VERSION,ctime(&curtime));
1253 out_printf(out,"/* Generated by GOB (v%s) on %s"
1254 " (do not edit directly) */\n\n",VERSION,ctime(&curtime));
1256 p = replace_sep(((Class *)class)->otype,'_');
1258 out_printf(outh,"#ifndef __%s_H__\n#define __%s_H__\n\n"
1259 "#include <gtk/gtk.h>\n\n",p,p);
1262 out_printf(outh,"#ifdef __cplusplus\n"
1264 "#endif /* __cplusplus */\n\n");
1266 out_printf(out,"#include \"%s.h\"\n\n",filebase);
1268 for(li=nodes;li;li=g_list_next(li)) {
1269 Node *node = li->data;
1270 if(node->type == CCODE_NODE) {
1271 CCode *cc = (CCode *)node;
1277 out_addline_infile(fp,cc->line_no);
1279 out_printf(fp,"\n%s\n",cc->cbuf->str);
1281 out_addline_outfile(fp);
1282 } else if(node->type == CLASS_NODE) {
1284 Class *c = (Class *)class;
1287 signals = count_signals(c);
1288 arguments = count_arguments(c);
1289 overrides = count_overrides(c);
1291 out_printf(outh,"\n#define %s(obj)\t"
1292 "GTK_CHECK_CAST((obj),%s_get_type(),%s)\n",
1293 macrobase,funcbase,typebase);
1294 out_printf(outh,"#define %s_CLASS(klass)\t"
1295 "GTK_CHECK_CLASS_CAST((klass),%s_get_type(),%sClass)\n",
1296 macrobase,funcbase,typebase);
1297 out_printf(outh,"#define %s(obj)\t"
1298 "GTK_CHECK_TYPE((obj), %s_get_type ())\n\n",
1301 otype = remove_sep(c->otype);
1302 ptype = remove_sep(c->ptype);
1303 out_printf(outh,"\ntypedef struct _%s %s;\n",otype,otype);
1304 out_printf(outh,"struct _%s {\n\t%s __parent__;\n",
1306 for(l=c->nodes;l;l=g_list_next(l)) {
1308 if(n->type == VARIABLE_NODE)
1309 put_variable((Variable *)n);
1311 out_printf(outh,"};\n");
1313 out_printf(outh,"\ntypedef struct _%sClass %sClass;\n",
1316 "struct _%sClass {\n\t%sClass __parent__;\n",
1318 for(l=c->nodes;l;l=g_list_next(l)) {
1320 if(n->type == METHOD_NODE)
1321 put_vs_method((Method *)n);
1323 out_printf(outh,"};\n\n");
1325 out_printf(outh,"guint\t%s_get_type\t(void);\n",funcbase);
1328 out_printf(out,"static void __object_set_arg "
1329 "(GtkObject *object, GtkArg *arg, "
1331 "static void __object_get_arg "
1332 "(GtkObject *object, GtkArg *arg, "
1333 "guint arg_id);\n");
1336 for(l=c->nodes;l;l=g_list_next(l)) {
1338 if(n->type == METHOD_NODE) {
1339 put_pub_method((Method *)n);
1340 put_priv_method_prot((Method *)n);
1345 for(l=c->nodes;l;l=g_list_next(l)) {
1347 if(n->type == METHOD_NODE) {
1348 add_signal_prots((Method *)n);
1359 out_printf(out,"#define GET_NEW (gtk_type_new(%s_get_type()))\n",
1365 add_getset_arg(c, TRUE);
1366 add_getset_arg(c, FALSE);
1369 for(l=c->nodes;l;l=g_list_next(l)) {
1371 if(n->type == METHOD_NODE) {
1372 put_method((Method *)n);
1376 out_printf(out,"#undef GET_NEW\n");
1383 g_assert_not_reached();
1386 out_printf(outh,"\n#ifdef __cplusplus\n"
1388 "#endif /* __cplusplus */\n\n"
1393 usage(poptContext optCon, int exitcode, char *error, char *addl)
1395 poptPrintUsage(optCon, stderr, 0);
1396 if (error) fprintf(stderr, "%s: %s", error, addl);
1402 main(int argc, char *argv[])
1407 struct poptOption optionsTable[] = {
1408 { "exit-on-warn", 'w', 0, &exit_on_warn, 0,
1409 "exit on warnings" },
1411 { NULL, 0, 0, NULL, 0 }
1414 optCon = poptGetContext(NULL, argc, argv, optionsTable, 0);
1415 poptSetOtherOptionHelp(optCon, "[OPTIONS]* [filename]");
1417 while ((c = poptGetNextOpt(optCon)) >= 0)
1420 filename = poptGetArg(optCon);
1421 if(!(poptPeekArg(optCon) == NULL))
1422 usage(optCon, 1, "Specify only one file",
1423 ".e.g., filename.gob");
1426 /* an error occurred during option processing */
1427 fprintf(stderr, "%s: %s\n",
1428 poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
1434 yyin = fopen(filename,"r");
1436 fprintf(stderr,"Error: can't open file '%s'\n",
1445 g_error("Parsing errors, quitting");
1447 print_error(FALSE," no class defined",0);
1451 exit_on_error = FALSE;
1452 make_inits((Class *)class);
1453 check_duplicate_symbols((Class *)class);
1454 check_duplicate_signals_args((Class *)class);
1455 check_public_new((Class *)class);
1456 check_vararg((Class *)class);
1457 exit_on_error = TRUE;
1464 generate_outfiles();
1469 poptFreeContext(optCon);