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,
36 char *filename = NULL;
46 static char *funcbase;
47 static char *pfuncbase;
48 static char *macrobase;
50 static char *typebase;
51 static char *ptypebase;
53 static int signals = 0;
54 static int arguments = 0;
55 static int overrides = 0;
60 int exit_on_warn = FALSE;
61 int exit_on_error = TRUE;
62 int got_error = FALSE;
65 print_error(int is_warn, char *error,int line)
75 fprintf(stderr,"%s:%d: %s %s\n",filename,line,w,error);
77 fprintf(stderr,"%s: %s %s\n",filename,w,error);
78 if((!is_warn || exit_on_warn) && exit_on_error)
83 remove_sep(char *base)
86 char *s = g_strdup(base);
87 while((p=strchr(s,':')))
93 replace_sep(char *base, char r)
96 char *s = g_strdup(base);
97 while((p=strchr(s,':')))
107 /*separate the namespace part and then replace rest of
110 separns_replace_sep(char *base, char **ns, char **name, char r)
113 char *s = g_strdup(base);
115 if((p=strchr(s,':')) && p!=s) {
122 while((p=strchr(s,':')))
125 *name = g_strdup(s+1);
132 make_is_macro(char *base)
137 separns_replace_sep(base,&s1,&s2,'_');
139 s = g_strconcat(s1,"_IS_",s2,NULL);
141 s = g_strconcat("IS_",s2,NULL);
154 filebase = replace_sep(((Class *)class)->otype,'-');
157 funcbase = replace_sep(((Class *)class)->otype,'_');
160 pfuncbase = replace_sep(((Class *)class)->ptype,'_');
161 g_strdown(pfuncbase);
163 macrobase = replace_sep(((Class *)class)->otype,'_');
166 macrois = make_is_macro(((Class *)class)->otype);
168 typebase = remove_sep(((Class *)class)->otype);
170 ptypebase = remove_sep(((Class *)class)->ptype);
174 def_methods(Class *c)
178 out_printf(out,"\n");
179 for(li=c->nodes;li;li=g_list_next(li)) {
180 Node *node = li->data;
181 if(node->type == METHOD_NODE) {
182 Method *m = (Method *)node;
184 if(m->scope == INIT_METHOD ||
185 m->scope == CLASS_INIT_METHOD ||
186 m->scope == OVERRIDE_METHOD)
189 out_printf(out,"#define %s %s_%s\n",m->id,funcbase,m->id);
192 out_printf(out,"\n");
196 undef_methods(Class *c)
200 out_printf(out,"\n");
201 for(li=c->nodes;li;li=g_list_next(li)) {
202 Node *node = li->data;
203 if(node->type == METHOD_NODE) {
204 Method *m = (Method *)node;
206 if(m->scope == INIT_METHOD ||
207 m->scope == CLASS_INIT_METHOD ||
208 m->scope == OVERRIDE_METHOD)
211 out_printf(out,"#undef %s\n",m->id);
214 out_printf(out,"\n");
218 print_type(FILE *fp, Type *t)
222 s = remove_sep(t->name);
223 out_printf(fp,"%s ",s);
226 for(i=0;i<t->stars;i++)
231 put_variable(Variable *v)
233 out_printf(outh,"\t");
234 if(v->scope == PRIVATE_SCOPE)
235 out_printf(outh,"/* private */ ");
236 print_type(outh,v->vtype);
238 out_printf(outh,"%s;\n",v->id);
242 print_method(FILE *fp, char *typeprefix, char *nameprefix,
243 char *namepostfix,char *postfix, Method *m)
247 out_printf(fp,"%s",typeprefix);
248 print_type(fp,m->mtype);
249 out_printf(fp,"%s%s_%s%s(",
250 nameprefix,funcbase,m->id,namepostfix);
253 for(li=m->args;li;li=g_list_next(li)) {
254 FuncArg *arg = li->data;
255 print_type(fp,arg->atype);
257 out_printf(fp,"%s, ",arg->name);
259 out_printf(fp,"%s",arg->name);
263 out_printf(fp,", ...");
265 out_printf(fp,"void");
267 out_printf(fp,")%s\n",postfix);
271 put_vs_method(Method *m)
273 if(m->scope != SIGNAL_LAST_METHOD &&
274 m->scope != SIGNAL_FIRST_METHOD &&
275 m->scope != PRIVATE_SIGNAL_LAST_METHOD &&
276 m->scope != PRIVATE_SIGNAL_FIRST_METHOD &&
277 m->scope != VIRTUAL_METHOD &&
278 m->scope != PRIVATE_VIRTUAL_METHOD)
281 print_method(outh,"\t","(* ",") ",";",m);
285 put_pub_method(Method *m)
287 if(m->scope == PRIVATE_SCOPE ||
288 m->scope == OVERRIDE_METHOD ||
289 m->scope == INIT_METHOD ||
290 m->scope == CLASS_INIT_METHOD ||
291 m->scope == PRIVATE_SIGNAL_LAST_METHOD ||
292 m->scope == PRIVATE_SIGNAL_FIRST_METHOD ||
293 m->scope == PRIVATE_VIRTUAL_METHOD)
296 print_method(outh,"","\t","\t",";",m);
300 put_priv_method_prot(Method *m)
302 if(m->scope == PUBLIC_SCOPE)
305 if(m->scope == PRIVATE_SIGNAL_LAST_METHOD ||
306 m->scope == PRIVATE_SIGNAL_FIRST_METHOD ||
307 m->scope == PRIVATE_VIRTUAL_METHOD) {
309 print_method(out,"static ","_real_"," ",";",m);
310 print_method(out,"static ",""," ",";",m);
311 } else if(m->scope == SIGNAL_LAST_METHOD ||
312 m->scope == SIGNAL_FIRST_METHOD ||
313 m->scope == VIRTUAL_METHOD) {
316 print_method(out,"static ","_real_"," ",";",m);
318 print_method(out,"static ",""," ",";",m);
323 make_init_args(Class *cl, char *name, int is_class)
330 tn = g_strconcat(cl->otype,":Class",NULL);
332 tn = g_strdup(cl->otype);
334 type = new_type(1,tn);
335 node = new_funcarg((Type *)type,name,NULL);
336 return g_list_prepend(NULL, node);
340 make_inits(Class *cl)
342 int got_class_init = FALSE;
343 int got_init = FALSE;
346 for(li=cl->nodes;li;li=g_list_next(li)) {
348 if(n->type == METHOD_NODE) {
349 Method *m = (Method *)n;
350 if(m->scope == INIT_METHOD) {
352 print_error(FALSE,"init defined more then once",m->line_no);
354 } else if(m->scope == CLASS_INIT_METHOD) {
356 print_error(FALSE,"class_init defined more then once",m->line_no);
357 got_class_init = TRUE;
361 if(!got_class_init) {
362 node = new_method(CLASS_INIT_METHOD,
363 (Type *)new_type(0,g_strdup("void")),
364 NULL,NULL,g_strdup("class_init"),
365 make_init_args(cl,g_strdup("c"),TRUE),
366 NULL, NULL,0,0,FALSE);
367 cl->nodes = g_list_prepend(cl->nodes,node);
370 node = new_method(INIT_METHOD,
371 (Type *)new_type(0,g_strdup("void")),
372 NULL,NULL,g_strdup("init"),
373 make_init_args(cl,g_strdup("o"),FALSE),
374 NULL, NULL,0,0,FALSE);
375 cl->nodes = g_list_prepend(cl->nodes,node);
379 static GHashTable *marsh = NULL;
382 add_signal_prots(Method *m)
388 if(m->scope != SIGNAL_LAST_METHOD &&
389 m->scope != SIGNAL_FIRST_METHOD &&
390 m->scope != PRIVATE_SIGNAL_LAST_METHOD &&
391 m->scope != PRIVATE_SIGNAL_FIRST_METHOD)
395 marsh = g_hash_table_new(NULL,NULL);
397 if(strcmp(m->gtktypes->data,"NONE")==0 &&
398 strcmp(m->gtktypes->next->data,"NONE")==0)
401 s = g_strdup_printf("__Sig%d",sig++);
403 g_hash_table_insert(marsh,m,s);
405 out_printf(out,"\ntypedef ");
406 print_type(out,m->mtype);
408 out_printf(out,"(*%s) (",s);
410 for(li=m->args;li;li=g_list_next(li)) {
411 FuncArg *arg = li->data;
412 print_type(out,arg->atype);
413 out_printf(out,", ");
415 out_printf(out,"gpointer);\n");
417 out_printf(out,"\nstatic void\n"
418 "marshal_%s (GtkObject * object,\n"
419 "\tGtkSignalFunc func,\n"
420 "\tgpointer func_data,\n"
424 if(strcmp(m->gtktypes->data,"NONE")==0) {
426 out_printf(out, "\t%s rfunc;\n\n"
427 "\trfunc = (%s)func;\n\n"
428 "\t(*rfunc)((%s *)object",s,s,typebase);
429 if(strcmp(m->gtktypes->next->data,"NONE")!=0) {
430 for(i=0,li=m->gtktypes->next;li;
431 i++,li=g_list_next(li)) {
432 out_printf(out, ",\n\t\tGTK_VALUE_%s(args[%d])",
436 out_printf(out, ",\n\t\tfunc_data);\n}\n\n");
439 out_printf(out, "\t%s rfunc;\n\t",s);
440 print_type(out,m->mtype);
441 out_printf(out, " *retval;\n\n"
442 "\trfunc = (%s)func;\n\n"
443 "\tretval = GTK_RETLOC_%s(args[%d]);\n\n"
444 "\t*retval = (*rfunc)((%s *)object",
445 s,(char *)m->gtktypes->data,
446 g_list_length(m->gtktypes)-1,typebase);
447 if(strcmp(m->gtktypes->next->data,"NONE")!=0) {
448 for(i=0,li=m->gtktypes->next;li;
449 i++,li=g_list_next(li)) {
450 out_printf(out, ",\n\t\tGTK_VALUE_%s(args[%d])",
454 out_printf(out, ",\n\t\tfunc_data);\n}\n\n");
463 out_printf(out,"\n");
465 out_printf(out,"enum {\n");
466 for(li=c->nodes;li;li=g_list_next(li)) {
468 if(n->type == METHOD_NODE) {
469 Method *m = (Method *)n;
470 if(m->scope == SIGNAL_LAST_METHOD ||
471 m->scope == SIGNAL_FIRST_METHOD ||
472 m->scope == PRIVATE_SIGNAL_LAST_METHOD ||
473 m->scope == PRIVATE_SIGNAL_FIRST_METHOD) {
474 char *s = g_strdup(m->id);
476 out_printf(out,"\t%s_SIGNAL,\n",s);
481 out_printf(out,"\tLAST_SIGNAL\n};\n\n");
484 out_printf(out,"enum {\n\tARG_0,\n");
485 for(li=c->nodes;li;li=g_list_next(li)) {
487 if(n->type == ARGUMENT_NODE) {
488 Argument *a = (Argument *)n;
489 char *s = g_strdup(a->name);
491 out_printf(out,"\tARG_%s,\n",s);
495 out_printf(out, "};\n\n");
500 "static guint object_signals[LAST_SIGNAL] = {0};\n\n");
502 out_printf(out, "static %sClass *parent_class = NULL;\n\n",ptypebase);
508 out_printf(out, "guint\n"
509 "%s_get_type (void)\n"
511 "\tstatic guint type = 0;\n\n"
513 "\t\tstatic const GtkTypeInfo info = {\n"
515 "\t\t\tsizeof (%s),\n"
516 "\t\t\tsizeof (%sClass),\n"
517 "\t\t\t(GtkClassInitFunc) %s_class_init,\n"
518 "\t\t\t(GtkObjectInitFunc) %s_init,\n"
519 "\t\t\t/* reserved_1 */ NULL,\n"
520 "\t\t\t/* reserved_2 */ NULL,\n"
521 "\t\t\t(GtkClassInitFunc) NULL,\n"
523 "\t\ttype = gtk_type_unique (%s_get_type(), &info);\n"
527 funcbase,typebase,typebase,typebase,
528 funcbase,funcbase,pfuncbase);
532 add_overrides(Class *c, char *oname, gboolean did_gtk_obj)
538 done = g_hash_table_new(g_str_hash,g_str_equal);
540 s = g_strdup("GtkObject"); /* This was already done */
541 g_hash_table_insert(done,s,s);
543 for(li=c->nodes;li;li=g_list_next(li)) {
547 if(n->type != METHOD_NODE ||
548 ((Method *)n)->scope != OVERRIDE_METHOD)
552 s = remove_sep(m->otype);
554 if(g_hash_table_lookup(done,s)) {
558 g_hash_table_insert(done,s,s);
560 f = replace_sep(m->otype,'_');
563 out_printf(out,"\t%sClass *%s_class = (%sClass *)%s;\n",
568 g_hash_table_foreach(done,(GHFunc)g_free,NULL);
569 g_hash_table_destroy(done);
573 add_signals(Class *c)
577 out_printf(out,"\n");
578 for(li=c->nodes;li;li=g_list_next(li)) {
585 if(n->type != METHOD_NODE ||
586 (((Method *)n)->scope != SIGNAL_FIRST_METHOD &&
587 ((Method *)n)->scope != SIGNAL_LAST_METHOD &&
588 ((Method *)n)->scope != PRIVATE_SIGNAL_FIRST_METHOD &&
589 ((Method *)n)->scope != PRIVATE_SIGNAL_LAST_METHOD))
594 if(m->scope == SIGNAL_FIRST_METHOD ||
595 m->scope == PRIVATE_SIGNAL_FIRST_METHOD)
600 if(g_hash_table_lookup(marsh,m))
601 mar = g_strconcat("marshal_",
602 (char *)g_hash_table_lookup(marsh,m),
605 mar = g_strdup("gtk_signal_default_marshaller");
607 is_none = (strcmp(m->gtktypes->next->data,"NONE")==0);
609 sig = g_strdup(m->id);
611 out_printf(out,"\tobject_signals[%s_SIGNAL] =\n"
612 "\t\tgtk_signal_new (\"%s\",\n"
613 "\t\t\tGTK_RUN_%s,\n"
614 "\t\t\tgtk_object_class->type,\n"
615 "\t\t\tGTK_SIGNAL_OFFSET (%sClass, %s),\n"
617 "\t\t\tGTK_TYPE_%s, %d",
620 typebase,m->id,mar,(char *)m->gtktypes->data,
621 is_none?0:g_list_length(m->gtktypes->next));
627 for(l=m->gtktypes->next;l;l=g_list_next(l))
628 out_printf(out,",\n\t\t\tGTK_TYPE_%s",
632 out_printf(out,");\n");
634 out_printf(out,"\tgtk_object_class_add_signals (gtk_object_class,\n"
635 "\t\tobject_signals, LAST_SIGNAL);\n\n");
639 set_def_handlers(Class *c, char *oname)
643 out_printf(out,"\n");
644 for(li=c->nodes;li;li=g_list_next(li)) {
647 if(n->type != METHOD_NODE ||
648 (((Method *)n)->scope != SIGNAL_FIRST_METHOD &&
649 ((Method *)n)->scope != SIGNAL_LAST_METHOD &&
650 ((Method *)n)->scope != PRIVATE_SIGNAL_FIRST_METHOD &&
651 ((Method *)n)->scope != PRIVATE_SIGNAL_LAST_METHOD &&
652 ((Method *)n)->scope != VIRTUAL_METHOD &&
653 ((Method *)n)->scope != PRIVATE_VIRTUAL_METHOD &&
654 ((Method *)n)->scope != OVERRIDE_METHOD))
659 if(m->scope == OVERRIDE_METHOD) {
661 s = replace_sep(m->otype,'_');
663 out_printf(out,"\t%s_class->%s = %s_%s;\n",
664 s,m->id,funcbase,m->id);
667 out_printf(out,"\t%s->%s = _real_%s_%s;\n",
668 oname,m->id,funcbase,m->id);
670 out_printf(out,"\t%s->%s = NULL;\n",
677 make_arguments(Class *c)
681 out_printf(out,"\n");
682 for(li=c->nodes;li;li=g_list_next(li)) {
688 if(n->type != ARGUMENT_NODE)
694 flags = g_string_new("GTK_ARG_READWRITE");
696 flags = g_string_new("GTK_ARG_READABLE");
698 flags = g_string_new("GTK_ARG_WRITABLE");
700 for(l=a->flags;l;l=g_list_next(l))
701 g_string_sprintfa(flags," | GTK_ARG_%s",(char *)l->data);
703 s = g_strdup(a->name);
705 out_printf(out,"\tgtk_object_add_arg_type(\"%s::%s\",\n"
709 typebase,a->name,a->gtktype,flags->str,s);
711 g_string_free(flags,TRUE);
715 "\n\tgtk_object_class->set_arg = __object_set_arg;\n"
716 "\tgtk_object_class->get_arg = __object_get_arg;\n");
723 for(li=c->nodes;li;li=g_list_next(li)) {
726 if(n->type != METHOD_NODE)
729 if(m->scope == INIT_METHOD) {
731 out_addline_infile(out,m->line_no);
732 print_method(out,"static ","\n"," ","",m);
734 out_addline_outfile(out);
735 out_printf(out,"{\n");
736 } else if(m->scope == CLASS_INIT_METHOD) {
738 out_addline_infile(out,m->line_no);
739 print_method(out,"static ","\n"," ","",m);
741 out_addline_outfile(out);
742 out_printf(out,"{\n");
747 "gtk_object_class = "
748 "(GtkObjectClass*) %s;\n",
749 ((FuncArg *)m->args->data)->name);
753 ((FuncArg *)m->args->data)->name,
754 (signals>0 || arguments>0));
756 out_printf(out,"\n\tparent_class = "
757 "gtk_type_class (%s_get_type ());\n",
763 set_def_handlers(c, ((FuncArg *)m->args->data)->name);
771 out_printf(out," {\n");
772 out_addline_infile(out,m->ccode_line);
773 out_printf(out,"%s\n",m->cbuf->str);
774 out_addline_outfile(out);
775 out_printf(out," }\n",m->cbuf->str);
777 out_printf(out,"return;\n");
779 out_printf(out,"}\n");
784 add_getset_arg(Class *c, int is_set)
787 out_printf(out,"\nstatic void\n"
788 "__object_%s_arg (GtkObject *object,\n"
792 "\t%s *self, *this;\n\n"
793 "\tself = this = %s (object);\n\n"
794 "\tswitch (arg_id) {\n",
795 is_set?"set":"get",typebase,macrobase);
797 for(li=c->nodes;li;li=g_list_next(li)) {
803 if(n->type != ARGUMENT_NODE)
808 line_no = a->set_line;
811 line_no = a->get_line;
815 s = g_strdup(a->name);
817 out_printf(out,"\tcase ARG_%s:\n"
818 "#define ARG (GTK_VALUE_%s(*arg))\n"
822 out_addline_infile(out,line_no);
823 out_printf(out,"%s\n",cbuf->str);
824 out_addline_outfile(out);
825 out_printf(out,"\t\t}\n\t\tbreak;\n"
828 out_printf(out,"\tdefault:\n\t\tbreak;\n\t}\n}\n");
832 print_checks(Method *m, FuncArg *fa)
836 is_void = (strcmp(m->mtype->name,"void")==0 &&
837 m->mtype->stars == 0);
839 for(li=fa->checks;li;li=g_list_next(li)) {
840 Check *ch = li->data;
843 out_printf(out,"\tg_return_if_fail (");
845 out_printf(out,"\tg_return_val_if_fail (");
848 out_printf(out,"%s != NULL",fa->name);
851 s = make_is_macro(fa->atype->name);
852 out_printf(out,"%s (%s)",s,fa->name);
856 out_printf(out,"%s < %s",fa->name,ch->number);
859 out_printf(out,"%s > %s",fa->name,ch->number);
862 out_printf(out,"%s <= %s",fa->name,ch->number);
865 out_printf(out,"%s >= %s",fa->name,ch->number);
868 out_printf(out,"%s == %s",fa->name,ch->number);
871 out_printf(out,"%s != %s",fa->name,ch->number);
875 out_printf(out,");\n");
877 out_printf(out,", (");
878 print_type(out,m->mtype);
879 out_printf(out,")%s);\n",
880 m->onerror?m->onerror:"0");
886 print_preconditions(Method *m)
890 for(li=m->args;li;li=g_list_next(li)) {
891 FuncArg *fa = li->data;
898 print_method_body(Method *m, int pre)
900 out_printf(out,"{\n");
902 print_preconditions(m);
903 out_printf(out,"\t{\n");
906 out_addline_infile(out,m->ccode_line);
907 out_printf(out,"\t\t%s\n",m->cbuf->str);
908 out_addline_outfile(out);
911 out_printf(out,"\t}\n");
912 out_printf(out,"}\n");
916 put_method(Method *m)
920 out_printf(out,"\n");
923 out_addline_infile(out,m->line_no);
924 print_method(out,"","\n"," ","",m);
925 print_method_body(m,TRUE);
928 out_addline_infile(out,m->line_no);
929 print_method(out,"static ","\n"," ","",m);
930 print_method_body(m,TRUE);
932 case PRIVATE_SIGNAL_FIRST_METHOD:
933 case PRIVATE_SIGNAL_LAST_METHOD:
935 case SIGNAL_FIRST_METHOD:
936 case SIGNAL_LAST_METHOD:
937 out_addline_infile(out,m->line_no);
938 print_method(out,private?"static ":"","\n"," ","",m);
939 out_addline_outfile(out);
940 out_printf(out,"{\n");
943 if(strcmp(m->mtype->name,"void")==0 &&
944 m->mtype->stars==0) {
946 print_preconditions(m);
947 if(((FuncArg *)m->args->data)->name)
948 out_printf(out,"\tgtk_signal_emit (GTK_OBJECT (%s),\n"
949 "\t\tobject_signals[%s_SIGNAL]",
950 ((FuncArg *)m->args->data)->name,s);
951 for(li=m->args->next;li;li=g_list_next(li)) {
952 FuncArg *fa = li->data;
953 out_printf(out,",\n\t\t%s",fa->name);
955 out_printf(out,");\n}\n");
958 out_printf(out,"\t");
959 print_type(out,m->mtype);
960 out_printf(out,"return_val;\n");
961 print_preconditions(m);
962 out_printf(out,"\tgtk_signal_emit (GTK_OBJECT (%s),\n"
963 "\t\tobject_signals[%s_SIGNAL]",
964 ((FuncArg *)m->args->data)->name,s);
965 for(li=m->args->next;li;li=g_list_next(li)) {
966 FuncArg *fa = li->data;
967 out_printf(out,",\n\t\t%s",fa->name);
969 out_printf(out,",\n\t\t&return_val);\n"
970 "\treturn return_val;\n}\n");
975 out_addline_infile(out,m->line_no);
976 print_method(out,"static ","\n_real_"," ","",m);
977 print_method_body(m,FALSE);
979 case PRIVATE_VIRTUAL_METHOD:
982 out_addline_infile(out,m->line_no);
983 print_method(out,private?"static ":"","\n"," ","",m);
984 out_addline_outfile(out);
986 "\t%sClass *class;\n",typebase);
987 print_preconditions(m);
988 out_printf(out,"\tclass = %s_CLASS(GTK_OBJECT(%s)->klass);\n\n"
990 macrobase, ((FuncArg *)m->args->data)->name, m->id);
991 if(strcmp(m->mtype->name,"void")==0 &&
992 m->mtype->stars==0) {
994 out_printf(out,"\t\t(*class->%s)(%s",m->id,
995 ((FuncArg *)m->args->data)->name);
996 for(li=m->args->next;li;li=g_list_next(li)) {
997 FuncArg *fa = li->data;
998 out_printf(out,",%s",fa->name);
1000 out_printf(out,");\n}\n");
1003 out_printf(out,"\t\treturn (*class->%s)(%s",m->id,
1004 ((FuncArg *)m->args->data)->name);
1005 for(li=m->args->next;li;li=g_list_next(li)) {
1006 FuncArg *fa = li->data;
1007 out_printf(out,",%s",fa->name);
1009 out_printf(out,");\n"
1012 print_type(out,m->mtype);
1013 out_printf(out,")(%s);\n}\n",
1014 m->onerror?m->onerror:"0");
1019 out_addline_infile(out,m->line_no);
1020 print_method(out,"static ","\n_real_"," ","",m);
1021 print_method_body(m,FALSE);
1023 case OVERRIDE_METHOD:
1024 out_addline_infile(out,m->line_no);
1025 print_method(out,"static ","\n"," ","",m);
1026 print_method_body(m,TRUE);
1034 check_duplicate(Class *c,Node *node,char *id, int line_no)
1037 for(l=c->nodes;l;l=g_list_next(l)) {
1042 if(n->type == METHOD_NODE) {
1043 Method *m = (Method *)n;
1045 nline_no = m->line_no;
1046 } else if(n->type == VARIABLE_NODE) {
1047 Variable *v = (Variable *)n;
1049 nline_no = v->line_no;
1053 line_no>=nline_no ||
1056 s = g_strdup_printf("symbol '%s' redefined, "
1057 "first defined on line %d",
1059 print_error(FALSE,s,nline_no);
1064 check_duplicate_symbols(Class *c)
1067 for(l=c->nodes;l;l=g_list_next(l)) {
1069 if(n->type == METHOD_NODE) {
1070 Method *m = (Method *)n;
1071 check_duplicate(c,n,m->id,m->line_no);
1072 } else if(n->type == VARIABLE_NODE) {
1073 Variable *v = (Variable *)n;
1074 check_duplicate(c,n,v->id,v->line_no);
1080 check_duplicate_named(Class *c,Node *node,char *id, int line_no)
1083 for(l=c->nodes;l;l=g_list_next(l)) {
1088 if(n->type == METHOD_NODE) {
1089 Method *m = (Method *)n;
1090 if(m->scope == SIGNAL_LAST_METHOD ||
1091 m->scope == SIGNAL_FIRST_METHOD ||
1092 m->scope == PRIVATE_SIGNAL_LAST_METHOD ||
1093 m->scope == PRIVATE_SIGNAL_FIRST_METHOD) {
1095 nline_no = m->line_no;
1098 } else if(n->type == ARGUMENT_NODE) {
1099 Argument *a = (Argument *)n;
1101 nline_no = a->line_no;
1105 line_no>=nline_no ||
1108 s = g_strdup_printf("named symbol (argument or signal) '%s' "
1109 "redefined, first defined on line %d",
1111 print_error(FALSE,s,nline_no);
1116 check_duplicate_signals_args(Class *c)
1119 for(l=c->nodes;l;l=g_list_next(l)) {
1121 if(n->type == METHOD_NODE) {
1122 Method *m = (Method *)n;
1123 if(m->scope == SIGNAL_LAST_METHOD ||
1124 m->scope == SIGNAL_FIRST_METHOD ||
1125 m->scope == PRIVATE_SIGNAL_LAST_METHOD ||
1126 m->scope == PRIVATE_SIGNAL_FIRST_METHOD)
1127 check_duplicate_named(c,n,m->id,m->line_no);
1128 } else if(n->type == ARGUMENT_NODE) {
1129 Argument *a = (Argument *)n;
1130 check_duplicate_named(c,n,a->name,a->line_no);
1136 check_public_new(Class *c)
1139 for(l=c->nodes;l;l=g_list_next(l)) {
1141 if(n->type == METHOD_NODE) {
1142 Method *m = (Method *)n;
1143 if(m->scope!=PUBLIC_SCOPE &&
1144 strcmp(m->id,"new")==0)
1146 "'new' should be a public method",
1153 check_vararg(Class *c)
1156 for(l=c->nodes;l;l=g_list_next(l)) {
1158 if(n->type == METHOD_NODE) {
1159 Method *m = (Method *)n;
1162 if(m->scope == OVERRIDE_METHOD ||
1163 m->scope == SIGNAL_LAST_METHOD ||
1164 m->scope == SIGNAL_FIRST_METHOD ||
1165 m->scope == PRIVATE_SIGNAL_LAST_METHOD ||
1166 m->scope == PRIVATE_SIGNAL_FIRST_METHOD ||
1167 m->scope == VIRTUAL_METHOD ||
1168 m->scope == PRIVATE_VIRTUAL_METHOD) {
1170 "signals, overrides and virtuals, "
1171 "can't have variable argument "
1180 count_signals(Class *c)
1184 for(l=c->nodes;l;l=g_list_next(l)) {
1186 if(n->type == METHOD_NODE) {
1187 Method *m = (Method *)n;
1188 if(m->scope == SIGNAL_LAST_METHOD ||
1189 m->scope == SIGNAL_FIRST_METHOD ||
1190 m->scope == PRIVATE_SIGNAL_LAST_METHOD ||
1191 m->scope == PRIVATE_SIGNAL_FIRST_METHOD)
1199 count_arguments(Class *c)
1204 for(li=c->nodes;li;li=g_list_next(li)) {
1206 if(n->type == ARGUMENT_NODE)
1213 count_overrides(Class *c)
1217 for(l=c->nodes;l;l=g_list_next(l)) {
1219 if(n->type == METHOD_NODE) {
1220 Method *m = (Method *)n;
1221 if(m->scope == OVERRIDE_METHOD)
1232 char *outfile,*outfileh;
1234 outfile = g_strconcat(filebase,".c",NULL);
1235 outfileh = g_strconcat(filebase,".h",NULL);
1237 out = fopen(outfile,"w");
1239 g_error("Cannot open outfile: %s",outfile);
1241 outh = fopen(outfileh,"w");
1243 g_error("Cannot open outfile: %s",outfileh);
1248 generate_outfiles(void)
1255 out_printf(outh,"/* Generated by GOB (v%s) on %s"
1256 " (do not edit directly) */\n\n",VERSION,ctime(&curtime));
1257 out_printf(out,"/* Generated by GOB (v%s) on %s"
1258 " (do not edit directly) */\n\n",VERSION,ctime(&curtime));
1260 p = replace_sep(((Class *)class)->otype,'_');
1262 out_printf(outh,"#ifndef __%s_H__\n#define __%s_H__\n\n"
1263 "#include <gtk/gtk.h>\n\n",p,p);
1266 out_printf(outh,"#ifdef __cplusplus\n"
1268 "#endif /* __cplusplus */\n\n");
1270 out_printf(out,"#include \"%s.h\"\n\n",filebase);
1272 for(li=nodes;li;li=g_list_next(li)) {
1273 Node *node = li->data;
1274 if(node->type == CCODE_NODE) {
1275 CCode *cc = (CCode *)node;
1279 out_printf(fp,"\n");
1282 out_printf(fp,"\n");
1283 out_addline_infile(fp,cc->line_no);
1285 out_printf(fp,"%s\n",cc->cbuf->str);
1287 out_addline_outfile(fp);
1288 } else if(node->type == CLASS_NODE) {
1290 Class *c = (Class *)class;
1293 signals = count_signals(c);
1294 arguments = count_arguments(c);
1295 overrides = count_overrides(c);
1297 out_printf(outh,"\n#define %s(obj)\t"
1298 "GTK_CHECK_CAST((obj),%s_get_type(),%s)\n",
1299 macrobase,funcbase,typebase);
1300 out_printf(outh,"#define %s_CLASS(klass)\t"
1301 "GTK_CHECK_CLASS_CAST((klass),%s_get_type(),%sClass)\n",
1302 macrobase,funcbase,typebase);
1303 out_printf(outh,"#define %s(obj)\t"
1304 "GTK_CHECK_TYPE((obj), %s_get_type ())\n\n",
1307 otype = remove_sep(c->otype);
1308 ptype = remove_sep(c->ptype);
1309 out_printf(outh,"\ntypedef struct _%s %s;\n",otype,otype);
1310 out_printf(outh,"struct _%s {\n\t%s __parent__;\n",
1312 for(l=c->nodes;l;l=g_list_next(l)) {
1314 if(n->type == VARIABLE_NODE)
1315 put_variable((Variable *)n);
1317 out_printf(outh,"};\n");
1319 out_printf(outh,"\ntypedef struct _%sClass %sClass;\n",
1322 "struct _%sClass {\n\t%sClass __parent__;\n",
1324 for(l=c->nodes;l;l=g_list_next(l)) {
1326 if(n->type == METHOD_NODE)
1327 put_vs_method((Method *)n);
1329 out_printf(outh,"};\n\n");
1331 out_printf(outh,"guint\t%s_get_type\t(void);\n",funcbase);
1334 out_printf(out,"static void __object_set_arg "
1335 "(GtkObject *object, GtkArg *arg, "
1337 "static void __object_get_arg "
1338 "(GtkObject *object, GtkArg *arg, "
1339 "guint arg_id);\n");
1342 for(l=c->nodes;l;l=g_list_next(l)) {
1344 if(n->type == METHOD_NODE) {
1345 put_pub_method((Method *)n);
1346 put_priv_method_prot((Method *)n);
1351 for(l=c->nodes;l;l=g_list_next(l)) {
1353 if(n->type == METHOD_NODE) {
1354 add_signal_prots((Method *)n);
1365 out_printf(out,"#define GET_NEW (gtk_type_new(%s_get_type()))\n",
1371 add_getset_arg(c, TRUE);
1372 add_getset_arg(c, FALSE);
1375 for(l=c->nodes;l;l=g_list_next(l)) {
1377 if(n->type == METHOD_NODE) {
1378 put_method((Method *)n);
1382 out_printf(out,"#undef GET_NEW\n");
1389 g_assert_not_reached();
1392 out_printf(outh,"\n#ifdef __cplusplus\n"
1394 "#endif /* __cplusplus */\n\n"
1400 usage(poptContext optCon, int exitcode, char *error, char *addl)
1402 poptPrintUsage(optCon, stderr, 0);
1403 if (error) fprintf(stderr, "%s: %s", error, addl);
1411 fprintf(stderr,"Gob version %s\n\n",VERSION);
1412 fprintf(stderr,"Options:\n"
1413 "\t--help,-h,-? Display this help\n"
1414 "\t--exit-on-warn,-w Exit with an error on warnings\n"
1415 "\t--no-exit-on-warn Don't exit on warnings [default]\n");
1419 parse_options(int argc, char *argv[])
1422 int got_file = FALSE;
1423 int no_opts = FALSE;
1427 for(i=1;i<argc;i++) {
1428 if(no_opts || argv[i][0]!='-') {
1431 fprintf(stderr,"Specify only one file!\n");
1437 } else if(strcmp(argv[i],"--help")==0) {
1440 } else if(strcmp(argv[i],"--exit-on-warn")==0) {
1441 exit_on_warn = TRUE;
1442 } else if(strcmp(argv[i],"--no-exit-on-warn")==0) {
1443 exit_on_warn = FALSE;
1444 } else if(strcmp(argv[i],"--")==0) {
1445 /*further arguments are files*/
1447 } else if(strncmp(argv[i],"--",2)==0) {
1448 /*unknown long option*/
1449 fprintf(stderr,"Unknown option '%s'!\n",argv[i]);
1453 /*by now we know we have a string starting with
1454 - which is a short option string*/
1455 char *p = argv[i]+1;
1456 for(p=argv[i]+1;*p;p++) {
1467 "Unknown option '%c'!\n",*p);
1477 main(int argc, char *argv[])
1483 struct poptOption optionsTable[] = {
1484 { "exit-on-warn", 'w', 0, &exit_on_warn, 0,
1485 "exit on warnings" },
1487 { NULL, 0, 0, NULL, 0 }
1490 optCon = poptGetContext(NULL, argc, argv, optionsTable, 0);
1491 poptSetOtherOptionHelp(optCon, "[OPTIONS]* [filename]");
1493 while ((c = poptGetNextOpt(optCon)) >= 0)
1496 filename = poptGetArg(optCon);
1497 if(!(poptPeekArg(optCon) == NULL))
1498 usage(optCon, 1, "Specify only one file",
1499 ".e.g., filename.gob");
1502 /* an error occurred during option processing */
1503 fprintf(stderr, "%s: %s\n",
1504 poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
1510 parse_options(argc,argv);
1513 yyin = fopen(filename,"r");
1515 fprintf(stderr,"Error: can't open file '%s'\n",
1524 g_error("Parsing errors, quitting");
1526 print_error(FALSE," no class defined",0);
1530 exit_on_error = FALSE;
1531 make_inits((Class *)class);
1532 check_duplicate_symbols((Class *)class);
1533 check_duplicate_signals_args((Class *)class);
1534 check_public_new((Class *)class);
1535 check_vararg((Class *)class);
1536 exit_on_error = TRUE;
1543 generate_outfiles();
1549 poptFreeContext(optCon);