/* GOB C Preprocessor
* Copyright (C) 1999-2000 the Free Software Foundation.
+ * Copyright (C) 2000 Eazel, Inc.
*
* Author: George Lebl
*
#include <stdio.h>
#include <glib.h>
-#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);
}
}
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 "
}
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;
continue;
if(n==node ||
line_no>=nline_no ||
- strcmp(nid,id)!=0)
+ g_strcasecmp(nid,id)!=0)
continue;
s = g_strdup_printf("named symbol (argument or signal) '%s' "
- "redefined, first defined on line %d",
+ "redefined, first defined on line %d "
+ "(case insensitive)",
id,line_no);
print_error(FALSE,s,nline_no);
}
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;
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;
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;
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;
void
check_nonvoidempty(Class *c)
{
- GList *l;
- for(l=c->nodes;l;l=g_list_next(l)) {
- Node *n = l->data;
+ 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;
if(m->method != REGULAR_METHOD)
continue;
- if(!(strcmp(m->mtype->name,"void")==0 &&
+ if(!(strcmp(m->mtype->name, "void")==0 &&
m->mtype->stars == 0) &&
!m->cbuf) {
print_error(TRUE,
void
check_signal_args(Class *c)
{
- GList *l;
- for(l=c->nodes;l;l=g_list_next(l)) {
- Node *n = l->data;
+ 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;
GList *l;
for(l=m->gtktypes;l;l=l->next) {
char *s;
- if(get_cast(l->data,FALSE))
+ if(get_cast(l->data, FALSE))
continue;
s = g_strdup_printf("Unknown GTK+ type '%s' "
"among signal types",
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;
char *s;
- if(get_cast(a->gtktype,FALSE))
+ if(get_cast(a->gtktype, FALSE))
continue;
s = g_strdup_printf("Unknown GTK+ type '%s' "
"as argument type",
{
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;
{
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 ++;
{
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;
{
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;
{
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;
}
return num;
}
+
+int
+count_destructors(Class *c)
+{
+ int num = 0;
+ GList *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;
+ if(v->destructor)
+ num++;
+ }
+ }
+ return num;
+}
+
+int
+count_initializers(Class *c)
+{
+ int num = 0;
+ GList *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;
+ if(v->initializer)
+ num++;
+ }
+ }
+ return num;
+}