]> git.draconx.ca Git - gob-dx.git/blobdiff - src/checks.c
Release 0.93.5
[gob-dx.git] / src / checks.c
index 726dad91957c50d354a4919e2372f3cac36d8e3a..7ce3bea967e83f2e2e2a26961a46781c13174c0b 100644 (file)
@@ -1,5 +1,6 @@
 /* GOB C Preprocessor
  * Copyright (C) 1999-2000 the Free Software Foundation.
+ * Copyright (C) 2000 Eazel, Inc.
  *
  * Author: George Lebl
  *
 #include "checks.h"
 
 static void
-check_duplicate(Class *c, Node *node, char *id, int line_no)
+check_duplicate(Class *c, Node *node, 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;
                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;
@@ -50,14 +61,24 @@ check_duplicate(Class *c, Node *node, char *id, int line_no)
                } else
                        continue;
                if(n == node ||
-                  line_no >= nline_no ||
-                  strcmp(nid, id) != 0 ||
-                  n->type != node->type)
+                  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);
+               /* 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);
        }
 }
 
@@ -69,14 +90,60 @@ check_duplicate_symbols(Class *c)
                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)
 {