X-Git-Url: https://git.draconx.ca/gitweb/gob-dx.git/blobdiff_plain/5b42e9400440d86723a27747b2191ab8cd59c2ee..486240dc4c5d57b0afaddba60d87fe375112bed5:/src/checks.c diff --git a/src/checks.c b/src/checks.c index f2bb058..7c675ee 100644 --- a/src/checks.c +++ b/src/checks.c @@ -1,5 +1,6 @@ /* GOB C Preprocessor * Copyright (C) 1999-2000 the Free Software Foundation. + * Copyright (C) 2000 Eazel, Inc. * * Author: George Lebl * @@ -24,40 +25,60 @@ #include #include -#include "tree.h" +#include "treefuncs.h" #include "main.h" #include "util.h" #include "checks.h" -void -check_duplicate(Class *c, Node *node, char *id, int line_no) +static void +check_duplicate(Class *c, Node *node, char *id, int line_no, + gboolean underscore) { GList *l; - for(l=c->nodes;l;l=g_list_next(l)) { + for(l = c->nodes; l != NULL; l = g_list_next(l)) { Node *n = l->data; char *nid; int nline_no; + gboolean here_underscore = FALSE; char *s; if(n->type == METHOD_NODE) { Method *m = (Method *)n; - nid = m->id; + + /* override methods are checked separately */ + if(m->method == OVERRIDE_METHOD) + continue; + + nid = get_real_id(m->id); nline_no = m->line_no; + + if(m->id[0] == '_' && m->id[1] != '\0') + here_underscore = TRUE; } else if(n->type == VARIABLE_NODE) { Variable *v = (Variable *)n; nid = v->id; nline_no = v->line_no; } else continue; - if(n==node || - line_no>=nline_no || - strcmp(nid,id)!=0 || - n->type != node->type) + if(n == node || + line_no > nline_no || + n->type != node->type || + strcmp(nid, id) != 0) continue; - s = g_strdup_printf("symbol '%s' redefined, " - "first defined on line %d", - id,line_no); - print_error(FALSE,s,nline_no); + /* 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); + 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); } } @@ -65,30 +86,76 @@ void check_duplicate_symbols(Class *c) { GList *l; - for(l=c->nodes;l;l=g_list_next(l)) { + for(l = c->nodes; l != NULL; l = g_list_next(l)) { Node *n = l->data; if(n->type == METHOD_NODE) { Method *m = (Method *)n; - check_duplicate(c,n,m->id,m->line_no); + gboolean underscore = FALSE; + /* override methods are checked separately */ + if(m->method == OVERRIDE_METHOD) + continue; + if(m->id[0] == '_' && m->id[1] != '\0') + underscore = TRUE; + check_duplicate(c, n, get_real_id(m->id), m->line_no, + underscore); } else if(n->type == VARIABLE_NODE) { Variable *v = (Variable *)n; - check_duplicate(c,n,v->id,v->line_no); + check_duplicate(c, n, v->id, v->line_no, FALSE); } } } +static void +check_duplicate_override(Class *c, Method *method) +{ + GList *l; + 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(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); + } +} + +void +check_duplicate_overrides(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 || + m->method != OVERRIDE_METHOD) + continue; + check_duplicate_override(c, m); + } +} + void check_bad_symbols(Class *c) { GList *l; - for(l=c->nodes;l;l=g_list_next(l)) { + for(l = c->nodes; l != NULL; l = g_list_next(l)) { Node *n = l->data; if(n->type == METHOD_NODE) { Method *m = (Method *)n; if((m->method == SIGNAL_LAST_METHOD || m->method == SIGNAL_FIRST_METHOD || m->method == VIRTUAL_METHOD) && - strcmp(m->id,"__parent__")==0) { + strcmp(m->id, "__parent__")==0) { char *s; s = g_strdup_printf("'%s' not allowed as an " "identifier of signal " @@ -99,33 +166,32 @@ check_bad_symbols(Class *c) } if(m->method != INIT_METHOD && m->method != CLASS_INIT_METHOD && - (strcmp(m->id,"init")==0 || - strcmp(m->id,"class_init")==0)) { + (strcmp(m->id, "init")==0 || + strcmp(m->id, "class_init")==0)) { print_error(FALSE,"init, or class_init not " "allowed as an " "identifier of non-" - "constructor methods",m->line_no); + "constructor methods", m->line_no); } } else if(n->type == VARIABLE_NODE) { Variable *v = (Variable *)n; - if(strcmp(v->id,"_priv")==0 || - strcmp(v->id,"__parent__")==0) { + 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); + "data member name", v->id); + print_error(FALSE, s, v->line_no); g_free(s); } } } } - -void -check_duplicate_named(Class *c,Node *node,char *id, int line_no) +static void +check_duplicate_named(Class *c, Node *node, char *id, int line_no) { GList *l; - for(l=c->nodes;l;l=g_list_next(l)) { + for(l = c->nodes; l != NULL; l = g_list_next(l)) { Node *n = l->data; char *nid; int nline_no; @@ -160,7 +226,7 @@ void check_duplicate_signals_args(Class *c) { GList *l; - for(l=c->nodes;l;l=g_list_next(l)) { + for(l = c->nodes; l != NULL; l = g_list_next(l)) { Node *n = l->data; if(n->type == METHOD_NODE) { Method *m = (Method *)n; @@ -178,7 +244,7 @@ void check_public_new(Class *c) { GList *l; - for(l=c->nodes;l;l=g_list_next(l)) { + for(l = c->nodes; l != NULL; l = g_list_next(l)) { Node *n = l->data; if(n->type == METHOD_NODE) { Method *m = (Method *)n; @@ -197,7 +263,7 @@ void check_vararg(Class *c) { GList *l; - for(l=c->nodes;l;l=g_list_next(l)) { + for(l = c->nodes; l != NULL; l = g_list_next(l)) { Node *n = l->data; if(n->type == METHOD_NODE) { Method *m = (Method *)n; @@ -221,7 +287,7 @@ void check_firstarg(Class *c) { GList *l; - for(l=c->nodes;l;l=g_list_next(l)) { + for(l = c->nodes; l != NULL; l = g_list_next(l)) { Node *n = l->data; if(n->type == METHOD_NODE) { Method *m = (Method *)n; @@ -244,14 +310,14 @@ void check_nonvoidempty(Class *c) { GList *li; - for(li=c->nodes; li; li=g_list_next(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; 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, "non-void empty method found, " @@ -273,7 +339,7 @@ void check_signal_args(Class *c) { GList *li; - for(li=c->nodes; li; li=g_list_next(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; @@ -300,7 +366,7 @@ void check_argument_types(Class *c) { GList *l; - for(l=c->nodes;l;l=g_list_next(l)) { + for(l = c->nodes; l != NULL; l = g_list_next(l)) { Node *n = l->data; if(n->type == ARGUMENT_NODE) { Argument *a = (Argument *)n; @@ -319,12 +385,95 @@ check_argument_types(Class *c) } } +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) { + print_error(FALSE, "Running checks on a void function " + "argument", m->line_no); + 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)) + goto type_check_error; + } + } + return; + +type_check_error: + if(fa->atype->pointer) + s = g_strdup_printf("Cannot check the type of '%s %s'", + fa->atype->name, fa->atype->pointer); + else + s = g_strdup_printf("Cannot check the type of '%s'", + fa->atype->name); + print_error(FALSE, s, m->line_no); + g_free(s); +} + +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); + } + } +} + int count_signals(Class *c) { int num = 0; GList *l; - for(l=c->nodes;l;l=g_list_next(l)) { + for(l = c->nodes; l != NULL; l = g_list_next(l)) { Node *n = l->data; if(n->type == METHOD_NODE) { Method *m = (Method *)n; @@ -341,8 +490,7 @@ count_arguments(Class *c) { int num = 0; GList *li; - - for(li=c->nodes;li;li=g_list_next(li)) { + for(li = c->nodes; li != NULL; li = g_list_next(li)) { Node *n = li->data; if(n->type == ARGUMENT_NODE) num ++; @@ -355,7 +503,7 @@ count_overrides(Class *c) { int num = 0; GList *l; - for(l=c->nodes;l;l=g_list_next(l)) { + for(l = c->nodes; l != NULL; l = g_list_next(l)) { Node *n = l->data; if(n->type == METHOD_NODE) { Method *m = (Method *)n; @@ -371,7 +519,7 @@ count_privates(Class *c) { int num = 0; GList *l; - for(l=c->nodes;l;l=g_list_next(l)) { + for(l = c->nodes; l != NULL; l = g_list_next(l)) { Node *n = l->data; if(n->type == VARIABLE_NODE) { Variable *v = (Variable *)n; @@ -387,7 +535,7 @@ count_protecteds(Class *c) { int num = 0; GList *l; - for(l=c->nodes;l;l=g_list_next(l)) { + for(l = c->nodes; l != NULL; l = g_list_next(l)) { Node *n = l->data; if(n->type == METHOD_NODE) { Method *m = (Method *)n; @@ -403,7 +551,7 @@ count_destructors(Class *c) { int num = 0; GList *l; - for(l=c->nodes;l;l=g_list_next(l)) { + for(l = c->nodes; l != NULL; l = g_list_next(l)) { Node *n = l->data; if(n->type == VARIABLE_NODE) { Variable *v = (Variable *)n; @@ -419,7 +567,7 @@ count_initializers(Class *c) { int num = 0; GList *l; - for(l=c->nodes;l;l=g_list_next(l)) { + for(l = c->nodes; l != NULL; l = g_list_next(l)) { Node *n = l->data; if(n->type == VARIABLE_NODE) { Variable *v = (Variable *)n;