2 * Copyright (C) 1999-2000 the Free Software Foundation.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
27 #include "treefuncs.h"
34 check_duplicate(Class *c, Node *node, char *id, int line_no)
37 for(l = c->nodes; l != NULL; l = g_list_next(l)) {
42 if(n->type == METHOD_NODE) {
43 Method *m = (Method *)n;
45 nline_no = m->line_no;
46 } else if(n->type == VARIABLE_NODE) {
47 Variable *v = (Variable *)n;
49 nline_no = v->line_no;
53 line_no >= nline_no ||
54 strcmp(nid, id) != 0 ||
55 n->type != node->type)
57 s = g_strdup_printf("symbol '%s' redefined, "
58 "first defined on line %d",
60 print_error(FALSE, s, nline_no);
65 check_duplicate_symbols(Class *c)
68 for(l = c->nodes; l != NULL; l = g_list_next(l)) {
70 if(n->type == METHOD_NODE) {
71 Method *m = (Method *)n;
72 check_duplicate(c, n, m->id, m->line_no);
73 } else if(n->type == VARIABLE_NODE) {
74 Variable *v = (Variable *)n;
75 check_duplicate(c, n, v->id, v->line_no);
81 check_bad_symbols(Class *c)
84 for(l = c->nodes; l != NULL; l = g_list_next(l)) {
86 if(n->type == METHOD_NODE) {
87 Method *m = (Method *)n;
88 if((m->method == SIGNAL_LAST_METHOD ||
89 m->method == SIGNAL_FIRST_METHOD ||
90 m->method == VIRTUAL_METHOD) &&
91 strcmp(m->id, "__parent__")==0) {
93 s = g_strdup_printf("'%s' not allowed as an "
94 "identifier of signal "
97 print_error(FALSE,s,m->line_no);
100 if(m->method != INIT_METHOD &&
101 m->method != CLASS_INIT_METHOD &&
102 (strcmp(m->id, "init")==0 ||
103 strcmp(m->id, "class_init")==0)) {
104 print_error(FALSE,"init, or class_init not "
107 "constructor methods", m->line_no);
109 } else if(n->type == VARIABLE_NODE) {
110 Variable *v = (Variable *)n;
111 if(strcmp(v->id, "_priv")==0 ||
112 strcmp(v->id, "__parent__")==0) {
114 s = g_strdup_printf("'%s' not allowed as a "
115 "data member name", v->id);
116 print_error(FALSE, s, v->line_no);
124 check_duplicate_named(Class *c, Node *node, char *id, int line_no)
127 for(l = c->nodes; l != NULL; l = g_list_next(l)) {
132 if(n->type == METHOD_NODE) {
133 Method *m = (Method *)n;
134 if(m->method == SIGNAL_LAST_METHOD ||
135 m->method == SIGNAL_FIRST_METHOD) {
137 nline_no = m->line_no;
140 } else if(n->type == ARGUMENT_NODE) {
141 Argument *a = (Argument *)n;
143 nline_no = a->line_no;
148 g_strcasecmp(nid,id)!=0)
150 s = g_strdup_printf("named symbol (argument or signal) '%s' "
151 "redefined, first defined on line %d "
152 "(case insensitive)",
154 print_error(FALSE,s,nline_no);
159 check_duplicate_signals_args(Class *c)
162 for(l = c->nodes; l != NULL; l = g_list_next(l)) {
164 if(n->type == METHOD_NODE) {
165 Method *m = (Method *)n;
166 if(m->method == SIGNAL_LAST_METHOD ||
167 m->method == SIGNAL_FIRST_METHOD)
168 check_duplicate_named(c,n,m->id,m->line_no);
169 } else if(n->type == ARGUMENT_NODE) {
170 Argument *a = (Argument *)n;
171 check_duplicate_named(c,n,a->name,a->line_no);
177 check_public_new(Class *c)
180 for(l = c->nodes; l != NULL; l = g_list_next(l)) {
182 if(n->type == METHOD_NODE) {
183 Method *m = (Method *)n;
184 if((strcmp(m->id,"new")==0) &&
185 (m->method != REGULAR_METHOD ||
186 m->scope != PUBLIC_SCOPE))
188 "'new' should be a regular\n"
196 check_vararg(Class *c)
199 for(l = c->nodes; l != NULL; l = g_list_next(l)) {
201 if(n->type == METHOD_NODE) {
202 Method *m = (Method *)n;
205 if(m->method == OVERRIDE_METHOD ||
206 m->method == SIGNAL_LAST_METHOD ||
207 m->method == SIGNAL_FIRST_METHOD ||
208 m->method == VIRTUAL_METHOD) {
210 "signals, overrides and virtuals, "
211 "can't have variable argument "
220 check_firstarg(Class *c)
223 for(l = c->nodes; l != NULL; l = g_list_next(l)) {
225 if(n->type == METHOD_NODE) {
226 Method *m = (Method *)n;
229 if(m->method == OVERRIDE_METHOD ||
230 m->method == SIGNAL_LAST_METHOD ||
231 m->method == SIGNAL_FIRST_METHOD ||
232 m->method == VIRTUAL_METHOD) {
234 "signals, overrides and virtuals, "
235 "can't have no arguments",
243 check_nonvoidempty(Class *c)
246 for(li = c->nodes; li != NULL; li = g_list_next(li)) {
248 if(n->type == METHOD_NODE) {
249 Method *m = (Method *)n;
250 if(m->method != REGULAR_METHOD)
252 if(!(strcmp(m->mtype->name, "void")==0 &&
253 m->mtype->stars == 0) &&
256 "non-void empty method found, "
257 "regular non-void function should "
260 /* add a body here, so that the user will also
261 get a warning from gcc, and so that it will
262 at least point him to the prototype of the
263 function in the .gob file */
264 m->cbuf = g_strdup("/*empty*/");
265 m->ccode_line = m->line_no;
272 check_signal_args(Class *c)
275 for(li = c->nodes; li != NULL; li = g_list_next(li)) {
277 if(n->type == METHOD_NODE) {
278 Method *m = (Method *)n;
280 if(m->method != SIGNAL_LAST_METHOD &&
281 m->method != SIGNAL_FIRST_METHOD)
284 for(l=m->gtktypes;l;l=l->next) {
286 if(get_cast(l->data, FALSE))
288 s = g_strdup_printf("Unknown GTK+ type '%s' "
289 "among signal types",
291 print_error(FALSE, s, m->line_no);
299 check_argument_types(Class *c)
302 for(l = c->nodes; l != NULL; l = g_list_next(l)) {
304 if(n->type == ARGUMENT_NODE) {
305 Argument *a = (Argument *)n;
307 if(get_cast(a->gtktype, FALSE))
309 s = g_strdup_printf("Unknown GTK+ type '%s' "
312 /* this could perhaps be a warning, but
313 can there really be a type beyond the
315 print_error(FALSE, s, a->line_no);
322 count_signals(Class *c)
326 for(l = c->nodes; l != NULL; l = g_list_next(l)) {
328 if(n->type == METHOD_NODE) {
329 Method *m = (Method *)n;
330 if(m->method == SIGNAL_LAST_METHOD ||
331 m->method == SIGNAL_FIRST_METHOD)
339 count_arguments(Class *c)
343 for(li = c->nodes; li != NULL; li = g_list_next(li)) {
345 if(n->type == ARGUMENT_NODE)
352 count_overrides(Class *c)
356 for(l = c->nodes; l != NULL; l = g_list_next(l)) {
358 if(n->type == METHOD_NODE) {
359 Method *m = (Method *)n;
360 if(m->method == OVERRIDE_METHOD)
368 count_privates(Class *c)
372 for(l = c->nodes; l != NULL; l = g_list_next(l)) {
374 if(n->type == VARIABLE_NODE) {
375 Variable *v = (Variable *)n;
376 if(v->scope == PRIVATE_SCOPE)
384 count_protecteds(Class *c)
388 for(l = c->nodes; l != NULL; l = g_list_next(l)) {
390 if(n->type == METHOD_NODE) {
391 Method *m = (Method *)n;
392 if(m->scope == PROTECTED_SCOPE)
400 count_destructors(Class *c)
404 for(l = c->nodes; l != NULL; l = g_list_next(l)) {
406 if(n->type == VARIABLE_NODE) {
407 Variable *v = (Variable *)n;
416 count_initializers(Class *c)
420 for(l = c->nodes; l != NULL; l = g_list_next(l)) {
422 if(n->type == VARIABLE_NODE) {
423 Variable *v = (Variable *)n;