X-Git-Url: http://git.draconx.ca/gitweb/gob-dx.git/blobdiff_plain/509cf0693fc440c71bdd3e71ea8947a6b4eb0bcf..714b58ab4606ed4d40cec3702cb378938f8c883f:/src/checks.c diff --git a/src/checks.c b/src/checks.c index 7ce3bea..062d635 100644 --- a/src/checks.c +++ b/src/checks.c @@ -32,16 +32,15 @@ #include "checks.h" static void -check_duplicate(Class *c, Node *node, char *id, int line_no, +check_duplicate(Class *c, Node *node, const char *id, int line_no, gboolean underscore) { GList *l; for(l = c->nodes; l != NULL; l = g_list_next(l)) { Node *n = l->data; - char *nid; + const char *nid; int nline_no; gboolean here_underscore = FALSE; - char *s; if(n->type == METHOD_NODE) { Method *m = (Method *)n; @@ -67,18 +66,18 @@ check_duplicate(Class *c, Node *node, char *id, int line_no, continue; /* this can only happen if the things were methods and * one had an underscore and the other one didn't */ - if(!no_kill_underscores && underscore != here_underscore) - s = g_strdup_printf("symbol '%s' ('_%s') redefined, " - "first defined on line %d. " - "Note that '%s' and '_%s' are " - "eqivalent.", - id, id, line_no, id, id); + if( ! no_kill_underscores && underscore != here_underscore) + error_printf(GOB_ERROR, nline_no, + "symbol '%s' ('_%s') redefined, " + "first defined on line %d. " + "Note that '%s' and '_%s' are " + "eqivalent.", + id, id, line_no, id, id); else - s = g_strdup_printf("symbol '%s' redefined, " - "first defined on line %d", - id, line_no); - print_error(FALSE, s, nline_no); - g_free(s); + error_printf(GOB_ERROR, nline_no, + "symbol '%s' redefined, " + "first defined on line %d", + id, line_no); } } @@ -112,21 +111,19 @@ check_duplicate_override(Class *c, Method *method) for(l = c->nodes; l != NULL; l = g_list_next(l)) { Node *n = l->data; Method *m = (Method *)n; - char *s; if(n->type != METHOD_NODE || m->method != OVERRIDE_METHOD) continue; if(method == m || method->line_no > m->line_no || - strcmp(m->id, method->id) != 0 || + strcmp(get_real_id(m->id), get_real_id(method->id)) != 0 || strcmp(m->otype, method->otype) != 0) continue; - s = g_strdup_printf("override '%s(%s)' redefined, " - "first defined on line %d", - m->id, m->otype, method->line_no); - print_error(FALSE, s, m->line_no); - g_free(s); + error_printf(GOB_ERROR, m->line_no, + "override '%s(%s)' redefined, " + "first defined on line %d", + get_real_id(m->id), m->otype, method->line_no); } } @@ -155,52 +152,49 @@ check_bad_symbols(Class *c) if((m->method == SIGNAL_LAST_METHOD || m->method == SIGNAL_FIRST_METHOD || m->method == 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); + (strcmp(m->id, "__parent__")==0 || + strcmp(m->id, "___parent__")==0)) { + error_printf(GOB_ERROR, m->line_no, + "'%s' not allowed as an " + "identifier of signal " + "or virtual methods", + m->id); } if(m->method != INIT_METHOD && m->method != CLASS_INIT_METHOD && - (strcmp(m->id, "init")==0 || - strcmp(m->id, "class_init")==0)) { - print_error(FALSE,"init, or class_init not " + (strcmp(get_real_id(m->id), "init")==0 || + strcmp(get_real_id(m->id), "class_init")==0)) { + error_print(GOB_ERROR, m->line_no, + "init, or class_init not " "allowed as an " "identifier of non-" - "constructor methods", m->line_no); + "constructor methods"); } } 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); + error_printf(GOB_ERROR, v->line_no, + "'%s' not allowed as a " + "data member name", v->id); } } } } static void -check_duplicate_named(Class *c, Node *node, char *id, int line_no) +check_duplicate_named(Class *c, Node *node, const char *id, int line_no) { GList *l; for(l = c->nodes; l != NULL; l = g_list_next(l)) { Node *n = l->data; - char *nid; + const char *nid; int nline_no; - char *s; if(n->type == METHOD_NODE) { Method *m = (Method *)n; if(m->method == SIGNAL_LAST_METHOD || m->method == SIGNAL_FIRST_METHOD) { - nid = m->id; + nid = get_real_id(m->id); nline_no = m->line_no; } else continue; @@ -210,15 +204,15 @@ check_duplicate_named(Class *c, Node *node, char *id, int line_no) nline_no = a->line_no; } else continue; - if(n==node || - line_no>=nline_no || - g_strcasecmp(nid,id)!=0) + if(n == node || + line_no >= nline_no || + g_strcasecmp(nid, id)!=0) continue; - s = g_strdup_printf("named symbol (argument or signal) '%s' " - "redefined, first defined on line %d " - "(case insensitive)", - id,line_no); - print_error(FALSE,s,nline_no); + error_printf(GOB_ERROR, nline_no, + "named symbol (argument or signal) '%s' " + "redefined, first defined on line %d " + "(case insensitive)", + id, line_no); } } @@ -232,10 +226,11 @@ check_duplicate_signals_args(Class *c) Method *m = (Method *)n; if(m->method == SIGNAL_LAST_METHOD || m->method == SIGNAL_FIRST_METHOD) - check_duplicate_named(c,n,m->id,m->line_no); + check_duplicate_named(c, n, get_real_id(m->id), + m->line_no); } else if(n->type == ARGUMENT_NODE) { Argument *a = (Argument *)n; - check_duplicate_named(c,n,a->name,a->line_no); + check_duplicate_named(c, n, a->name, a->line_no); } } } @@ -248,13 +243,12 @@ check_public_new(Class *c) Node *n = l->data; if(n->type == METHOD_NODE) { Method *m = (Method *)n; - if((strcmp(m->id,"new")==0) && + if((strcmp(get_real_id(m->id), "new")==0) && (m->method != REGULAR_METHOD || m->scope != PUBLIC_SCOPE)) - print_error(TRUE, + error_print(GOB_WARN, m->line_no, "'new' should be a regular\n" - "public method", - m->line_no); + "public method"); } } } @@ -267,17 +261,16 @@ check_vararg(Class *c) Node *n = l->data; if(n->type == METHOD_NODE) { Method *m = (Method *)n; - if(!m->vararg) + if( ! m->vararg) continue; if(m->method == OVERRIDE_METHOD || m->method == SIGNAL_LAST_METHOD || m->method == SIGNAL_FIRST_METHOD || m->method == VIRTUAL_METHOD) { - print_error(FALSE, + error_print(GOB_ERROR, m->line_no, "signals, overrides and virtuals, " "can't have variable argument " - "lists", - m->line_no); + "lists"); } } } @@ -297,10 +290,9 @@ check_firstarg(Class *c) m->method == SIGNAL_LAST_METHOD || m->method == SIGNAL_FIRST_METHOD || m->method == VIRTUAL_METHOD) { - print_error(FALSE, + error_print(GOB_ERROR, m->line_no, "signals, overrides and virtuals, " - "can't have no arguments", - m->line_no); + "can't have no arguments"); } } } @@ -317,13 +309,12 @@ check_nonvoidempty(Class *c) if(m->method != REGULAR_METHOD) continue; if(!(strcmp(m->mtype->name, "void")==0 && - m->mtype->stars == 0) && + m->mtype->pointer == NULL) && !m->cbuf) { - print_error(TRUE, + error_print(GOB_WARN, m->line_no, "non-void empty method found, " "regular non-void function should " - "not be empty.", - m->line_no); + "not be empty."); /* add a body here, so that the user will also get a warning from gcc, and so that it will at least point him to the prototype of the @@ -349,14 +340,12 @@ check_signal_args(Class *c) continue; for(l=m->gtktypes;l;l=l->next) { - char *s; if(get_cast(l->data, FALSE)) continue; - s = g_strdup_printf("Unknown GTK+ type '%s' " - "among signal types", - (char *)l->data); - print_error(FALSE, s, m->line_no); - g_free(s); + error_printf(GOB_ERROR, m->line_no, + "Unknown GTK+ type '%s' " + "among signal types", + (char *)l->data); } } } @@ -370,17 +359,99 @@ check_argument_types(Class *c) Node *n = l->data; if(n->type == ARGUMENT_NODE) { Argument *a = (Argument *)n; - char *s; if(get_cast(a->gtktype, FALSE)) continue; - s = g_strdup_printf("Unknown GTK+ type '%s' " - "as argument type", - a->gtktype); /* this could perhaps be a warning, but can there really be a type beyond the fundementals? */ - print_error(FALSE, s, a->line_no); + error_printf(GOB_ERROR, a->line_no, + "Unknown GTK+ type '%s' " + "as argument type", + a->gtktype); + } + } +} + +static void +check_func_arg_check_func_arg(Method *m, FuncArg *fa) +{ + GList *li; + char *s; + + if( ! fa->checks) + return; + + if(strcmp(fa->atype->name, "void") == 0 && + fa->atype->pointer == NULL) { + error_print(GOB_ERROR, m->line_no, + "Running checks on a void function argument"); + return; + } + + for(li = fa->checks; li; li = g_list_next(li)) { + Check *ch = li->data; + if(ch->chtype == TYPE_CHECK) { + char *p; + gboolean got_type = FALSE; + s = g_strdup(fa->atype->name); + p = strtok(s, " "); + if( ! p) { + g_free(s); + goto type_check_error; + } + while(p) { + if(strcmp(p, "const") != 0) { + if(got_type) { + g_free(s); + goto type_check_error; + } + got_type = TRUE; + } + p = strtok(NULL, " "); + } g_free(s); + if( ! got_type) + goto type_check_error; + + if(fa->atype->pointer == NULL || + (strcmp(fa->atype->pointer, "*") != 0 && + strcmp(fa->atype->pointer, "* const") != 0 && + strcmp(fa->atype->pointer, "const *") != 0)) + goto type_check_error; + } + } + return; + +type_check_error: + if(fa->atype->pointer) + error_printf(GOB_ERROR, m->line_no, + "Cannot check the type of '%s %s'", + fa->atype->name, fa->atype->pointer); + else + error_printf(GOB_ERROR, m->line_no, + "Cannot check the type of '%s'", + fa->atype->name); +} + +static void +check_func_arg_check_method(Method *m) +{ + GList *li; + for(li = m->args; li; li = g_list_next(li)) { + FuncArg *fa = li->data; + check_func_arg_check_func_arg(m, fa); + } +} + +void +check_func_arg_checks(Class *c) +{ + GList *li; + for(li = c->nodes; li != NULL; li = g_list_next(li)) { + Node *n = li->data; + if(n->type == METHOD_NODE) { + Method *m = (Method *)n; + check_func_arg_check_method(m); } } } @@ -403,13 +474,30 @@ count_signals(Class *c) } int -count_arguments(Class *c) +count_set_arguments(Class *c) { int num = 0; GList *li; for(li = c->nodes; li != NULL; li = g_list_next(li)) { Node *n = li->data; - if(n->type == ARGUMENT_NODE) + Argument *a = li->data; + if(n->type == ARGUMENT_NODE && + a->set) + num ++; + } + return num; +} + +int +count_get_arguments(Class *c) +{ + int num = 0; + GList *li; + for(li = c->nodes; li != NULL; li = g_list_next(li)) { + Node *n = li->data; + Argument *a = li->data; + if(n->type == ARGUMENT_NODE && + a->get) num ++; } return num; @@ -494,3 +582,27 @@ count_initializers(Class *c) } return num; } + +gboolean +find_get_type (Class *c) +{ + GList *l; + for(l = c->nodes; l != NULL; l = g_list_next(l)) { + Node *n = l->data; + Method *m = (Method *)n; + if(n->type == METHOD_NODE && + strcmp (m->id, "get_type") == 0) { + if (m->method != REGULAR_METHOD || + m->scope != PUBLIC_SCOPE || + m->args != NULL) { + error_printf (GOB_ERROR, m->line_no, + "get_type method must be a " + "regular public method with " + "no arguments"); + } + return TRUE; + } + } + + return FALSE; +}