X-Git-Url: http://git.draconx.ca/gitweb/gob-dx.git/blobdiff_plain/a611f21fab136f64bbf979bd62b2fc6ecb62933c..40647d7b7b7fbeae828e0a032a3c3a5f204cdfa8:/src/main.c diff --git a/src/main.c b/src/main.c index e556006..07158f5 100644 --- a/src/main.c +++ b/src/main.c @@ -44,6 +44,8 @@ extern FILE * yyin; extern Node *class; extern GList *nodes; +extern GList *include_files; + char *filebase; static char *funcbase; static char *pfuncbase; @@ -53,9 +55,10 @@ static char *macrotype; static char *typebase; static char *ptypebase; -static int signals = 0; -static int arguments = 0; -static int overrides = 0; +static int signals = 0; /* number of signals */ +static int arguments = 0; /* number of named arguments */ +static int overrides = 0; /* number of override functions */ +static int privates = 0; /* number of private data members */ FILE *out; FILE *outh; @@ -288,14 +291,17 @@ add_bad_hack_to_avoid_unused_warnings(Class *c) } static void -put_variable(Variable *v) +put_variable(Variable *v, FILE *fp, int priv) { - out_printf(outh,"\t"); - if(v->scope == PRIVATE_SCOPE) - out_printf(outh,"/* private */ "); - print_type(outh,v->vtype); + if(v->scope == PRIVATE_SCOPE) { + if(!priv) return; + } else { + if(priv) return; + } - out_printf(outh,"%s;\n",v->id); + out_printf(fp,"\t"); + print_type(fp,v->vtype); + out_printf(fp,"%s;\n",v->id); } static void @@ -351,16 +357,16 @@ put_priv_method_prot(Method *m) } static GList * -make_init_args(Class *cl, char *name, int is_class) +make_func_arg(char *typename, int is_class, char *name) { Node *node; Node *type; char *tn; if(is_class) - tn = g_strconcat(cl->otype,":Class",NULL); + tn = g_strconcat(typename,":Class",NULL); else - tn = g_strdup(cl->otype); + tn = g_strdup(typename); type = new_type(1,tn); node = new_funcarg((Type *)type,name,NULL); @@ -393,7 +399,7 @@ make_inits(Class *cl) node = new_method(CLASS_INIT_METHOD, (Type *)new_type(0,g_strdup("void")), NULL,NULL,g_strdup("class_init"), - make_init_args(cl,g_strdup("c"),TRUE), + make_func_arg(cl->otype,TRUE,g_strdup("c")), NULL, NULL,0,0,FALSE); cl->nodes = g_list_prepend(cl->nodes,node); } @@ -401,12 +407,50 @@ make_inits(Class *cl) node = new_method(INIT_METHOD, (Type *)new_type(0,g_strdup("void")), NULL,NULL,g_strdup("init"), - make_init_args(cl,g_strdup("o"),FALSE), + make_func_arg(cl->otype,FALSE,g_strdup("o")), NULL, NULL,0,0,FALSE); cl->nodes = g_list_prepend(cl->nodes,node); } } +static void +make_destroy(Class *cl) +{ + int got_destroy = FALSE; + GList *li; + Node *node; + for(li=cl->nodes;li;li=g_list_next(li)) { + Node *n = li->data; + if(n->type == METHOD_NODE) { + Method *m = (Method *)n; + if(m->scope == OVERRIDE_METHOD && + strcmp(m->id,"destroy")==0) { + if(strcmp(m->otype,"Gtk:Object")==0) { + got_destroy = TRUE; + break; + } else { + print_error(FALSE,"destroy method override " + "of class other then Gtk:Object", + m->line_no); + } + + } + } + } + if(!got_destroy) { + node = new_method(OVERRIDE_METHOD, + (Type *)new_type(0,g_strdup("void")), + g_strdup("Gtk:Object"), + NULL,g_strdup("destroy"), + make_func_arg("Gtk:Object",FALSE,g_strdup("o")), + NULL, + g_string_new("PARENT_HANDLER (o);\n"), + 0,0,FALSE); + cl->nodes = g_list_append(cl->nodes,node); + overrides++; + } +} + static GHashTable *marsh = NULL; static void @@ -786,6 +830,12 @@ add_inits(Class *c) if(m->line_no>0) out_addline_outfile(out); out_printf(out,"{\n"); + if(privates>0) { + out_printf(out,"\t%s->_priv = " + "g_new0 (%sPrivate,1);\n", + ((FuncArg *)m->args->data)->name, + typebase); + } } else if(m->scope == CLASS_INIT_METHOD) { if(m->line_no>0) out_addline_infile(out,m->line_no); @@ -950,21 +1000,39 @@ print_preconditions(Method *m) } } +/* put in code if it's needed */ +static void +put_in_gen_code(Method *m) +{ + /* now we only have the freeing of the private structure */ + if(privates>0 && + m->scope == OVERRIDE_METHOD && + strcmp(m->id,"destroy")==0) { + out_printf(out,"\tg_free (%s (%s)->_priv);\n" + "\t%s (%s)->_priv = NULL;\n", + macrobase, + ((FuncArg *)m->args->data)->name, + macrobase, + ((FuncArg *)m->args->data)->name); + + } +} + static void print_method_body(Method *m, int pre) { out_printf(out,"{\n"); - if(pre) { + if(pre) print_preconditions(m); - out_printf(out,"\t{\n"); - } + put_in_gen_code(m); + + out_printf(out,"\t{\n"); out_addline_infile(out,m->ccode_line); out_printf(out,"\t\t%s\n",m->cbuf->str); out_addline_outfile(out); - if(pre) - out_printf(out,"\t}\n"); + out_printf(out,"\t}\n"); out_printf(out,"}\n"); } @@ -1141,6 +1209,44 @@ check_duplicate_symbols(Class *c) } } +static void +check_bad_symbols(Class *c) +{ + GList *l; + for(l=c->nodes;l;l=g_list_next(l)) { + Node *n = l->data; + if(n->type == METHOD_NODE) { + Method *m = (Method *)n; + if((m->scope == SIGNAL_LAST_METHOD || + m->scope == SIGNAL_FIRST_METHOD || + m->scope == PRIVATE_SIGNAL_LAST_METHOD || + m->scope == PRIVATE_SIGNAL_FIRST_METHOD || + m->scope == VIRTUAL_METHOD || + m->scope == PRIVATE_VIRTUAL_METHOD) && + strcmp(m->id,"__parent__")==0) { + char *s; + s = g_strdup_printf("'%s' not allowed as an " + "identifier of signal " + "or virtual methods", + m->id); + print_error(FALSE,s,m->line_no); + g_free(s); + } + } else if(n->type == VARIABLE_NODE) { + Variable *v = (Variable *)n; + if(strcmp(v->id,"_priv")==0 || + strcmp(v->id,"__parent__")==0) { + char *s; + s = g_strdup_printf("'%s' not allowed as a data " + "member name",v->id); + print_error(FALSE,s,v->line_no); + g_free(s); + } + } + } +} + + static void check_duplicate_named(Class *c,Node *node,char *id, int line_no) { @@ -1241,6 +1347,32 @@ check_vararg(Class *c) } } +static void +check_firstarg(Class *c) +{ + GList *l; + for(l=c->nodes;l;l=g_list_next(l)) { + Node *n = l->data; + if(n->type == METHOD_NODE) { + Method *m = (Method *)n; + if(m->args) + continue; + if(m->scope == OVERRIDE_METHOD || + m->scope == SIGNAL_LAST_METHOD || + m->scope == SIGNAL_FIRST_METHOD || + m->scope == PRIVATE_SIGNAL_LAST_METHOD || + m->scope == PRIVATE_SIGNAL_FIRST_METHOD || + m->scope == VIRTUAL_METHOD || + m->scope == PRIVATE_VIRTUAL_METHOD) { + print_error(FALSE, + "signals, overrides and virtuals, " + "can't have no arguments", + m->line_no); + } + } + } +} + static int count_signals(Class *c) { @@ -1290,6 +1422,22 @@ count_overrides(Class *c) return num; } +static int +count_privates(Class *c) +{ + int num = 0; + GList *l; + for(l=c->nodes;l;l=g_list_next(l)) { + Node *n = l->data; + if(n->type == VARIABLE_NODE) { + Variable *v = (Variable *)n; + if(v->scope == PRIVATE_SCOPE) + num++; + } + } + return num; +} + static void open_files(void) @@ -1339,8 +1487,11 @@ generate_outfiles(void) "extern \"C\" {\n" "#endif /* __cplusplus */\n\n"); - out_printf(out,"#include \"%s.h\"\n\n",filebase); - + p = g_strconcat(filebase,".h",NULL); + if(!g_list_find_custom(include_files,p,(GCompareFunc)strcmp)) + out_printf(out,"#include \"%s.h\"\n\n",filebase); + g_free(p); + for(li=nodes;li;li=g_list_next(li)) { Node *node = li->data; if(node->type == CCODE_NODE) { @@ -1358,13 +1509,8 @@ generate_outfiles(void) if(!cc->header) out_addline_outfile(fp); } else if(node->type == CLASS_NODE) { - GList *l; Class *c = (Class *)class; - char *otype,*ptype; - - signals = count_signals(c); - arguments = count_arguments(c); - overrides = count_overrides(c); + GList *l; out_printf(outh,"\n#define %s\t" "(%s_get_type())\n", @@ -1379,23 +1525,41 @@ generate_outfiles(void) "GTK_CHECK_TYPE((obj), %s_get_type ())\n\n", macrois,funcbase); - otype = remove_sep(c->otype); - ptype = remove_sep(c->ptype); - out_printf(outh,"\ntypedef struct _%s %s;\n",otype,otype); + if(privates>0) + out_printf(outh,"\ntypedef struct _%sPrivate %sPrivate;\n",typebase,typebase); + + out_printf(outh,"\ntypedef struct _%s %s;\n",typebase,typebase); out_printf(outh,"struct _%s {\n\t%s __parent__;\n", - otype,ptype); + typebase,ptypebase); for(l=c->nodes;l;l=g_list_next(l)) { Node *n = l->data; if(n->type == VARIABLE_NODE) - put_variable((Variable *)n); + put_variable((Variable *)n,outh,FALSE); } + if(privates>0) + out_printf(outh,"\t%sPrivate *_priv;\n",typebase); out_printf(outh,"};\n"); + if(privates>0) { + out_printf(out,"struct _%sPrivate {\n", + typebase); + for(l=c->nodes;l;l=l->next) { + Node *n = l->data; + if(n->type == VARIABLE_NODE) { + Variable *v = (Variable *)n; + out_addline_infile(out,v->line_no); + put_variable(v,out,TRUE); + } + } + out_addline_outfile(out); + out_printf(out,"};\n"); + } + out_printf(outh,"\ntypedef struct _%sClass %sClass;\n", - otype,otype); + typebase,typebase); out_printf(outh, "struct _%sClass {\n\t%sClass __parent__;\n", - otype,ptype); + typebase,ptypebase); for(l=c->nodes;l;l=g_list_next(l)) { Node *n = l->data; if(n->type == METHOD_NODE) @@ -1457,9 +1621,6 @@ generate_outfiles(void) out_printf(out,"#undef GET_NEW\n"); add_bad_hack_to_avoid_unused_warnings(c); - - g_free(otype); - g_free(ptype); } else g_assert_not_reached(); } @@ -1635,14 +1796,25 @@ main(int argc, char *argv[]) if(!class) print_error(FALSE," no class defined",0); - make_bases(); - + exit_on_error = FALSE; + + signals = count_signals((Class *)class); + arguments = count_arguments((Class *)class); + overrides = count_overrides((Class *)class); + privates = count_privates((Class *)class); + + make_bases(); make_inits((Class *)class); + if(privates>0) + make_destroy((Class *)class); + check_bad_symbols((Class *)class); check_duplicate_symbols((Class *)class); check_duplicate_signals_args((Class *)class); check_public_new((Class *)class); check_vararg((Class *)class); + check_firstarg((Class *)class); + exit_on_error = TRUE; if(got_error)