diff --git a/src/language.yacc b/src/language.yacc index 794fc9a19494894b43f2af28def38ab6f206fa29..c7ea22e84dfc53307d369daf1221cece68a5b876 100644 --- a/src/language.yacc +++ b/src/language.yacc @@ -2,7 +2,7 @@ || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. -|| $Id: language.yacc,v 1.424 2008/05/18 13:42:09 grubba Exp $ +|| $Id: language.yacc,v 1.425 2008/05/24 15:14:12 grubba Exp $ */ %pure_parser @@ -155,6 +155,7 @@ /* #define LAMBDA_DEBUG 1 */ +static void yyerror_reserved(const char *keyword); static struct pike_string *get_new_name(); int add_local_name(struct pike_string *, struct pike_type *, node *); int low_add_local_name(struct compiler_frame *, @@ -4390,48 +4391,9 @@ bad_expr_ident: %% -void low_yyerror(struct pike_string *str) -{ - struct compilation *c = MAYBE_THIS_COMPILATION; - extern int cumulative_parse_error; - - if (!c) return; - - STACK_LEVEL_START(0); - -#ifdef PIKE_DEBUG - if(Pike_interpreter.recoveries && Pike_sp-Pike_interpreter.evaluator_stack < Pike_interpreter.recoveries->stack_pointer) - Pike_fatal("Stack error (underflow)\n"); -#endif - - CHECK_COMPILER(); - - if (Pike_compiler->num_parse_error > 20) return; - Pike_compiler->num_parse_error++; - cumulative_parse_error++; - - push_int(REPORT_ERROR); - ref_push_string(c->lex.current_file); - push_int(c->lex.current_line); - push_constant_text("parse"); - ref_push_string(str); - safe_apply_current(PC_REPORT_FUN_NUM, 5); - pop_stack(); - STACK_LEVEL_DONE(0); -} - -PMOD_EXPORT void yyerror(const char *str) -{ - push_text(str); - low_yyerror(Pike_sp[-1].u.string); - pop_stack(); -} - static void yyerror_reserved(const char *keyword) { - char fmt[100]; - SNPRINTF(fmt, sizeof(fmt), "%s is a reserved word.", keyword); - yyerror(fmt); + my_yyerror("%s is a reserved word.", keyword); } static struct pike_string *get_new_name() diff --git a/src/las.c b/src/las.c index 6bfcddadb6c41bf3d34b94ac393000951ed51cdb..bfedd118c401a131bbfbe4c5bec20f48d3a77428 100644 --- a/src/las.c +++ b/src/las.c @@ -2,7 +2,7 @@ || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. -|| $Id: las.c,v 1.412 2008/05/18 15:37:28 grubba Exp $ +|| $Id: las.c,v 1.413 2008/05/24 15:14:12 grubba Exp $ */ #include "global.h" @@ -373,11 +373,11 @@ static int check_node_type(node *n, struct pike_type *t, const char *msg) { if (pike_types_le(n->type, t)) return 1; if (!match_types(n->type, t)) { - yytype_error(msg, t, n->type, 0); + yytype_report(REPORT_ERROR, NULL, 0, t, NULL, 0, n->type, 0, msg); return 0; } if (THIS_COMPILATION->lex.pragmas & ID_STRICT_TYPES) { - yytype_error(msg, t, n->type, YYTE_IS_WARNING); + yytype_report(REPORT_WARNING, NULL, 0, t, NULL, 0, n->type, 0, msg); } if (runtime_options & RUNTIME_CHECK_TYPES) { node *p = n->parent; @@ -1323,28 +1323,28 @@ node *debug_mksoftcastnode(struct pike_type *type, node *n) if (n->type) { #ifdef NEW_ARG_CHECK if (!(result_type = soft_cast(type, n->type, 0))) { - struct pike_string *t1 = describe_type(type); - struct pike_string *t2 = describe_type(n->type); - my_yyerror("Soft cast of %S to %S isn't a valid cast.", - t2, t1); - free_string(t2); - free_string(t1); + ref_push_type_value(n->type); + ref_push_type_value(type); + yytype_report(REPORT_ERROR, + NULL, 0, NULL, + NULL, 0, NULL, + 2, "Soft cast of %O to %O isn't a valid cast."); } else if (result_type == n->type) { - struct pike_string *t1 = describe_type(type); - struct pike_string *t2 = describe_type(n->type); - yywarning("Soft cast of %S to %S is a noop.", - t2, t1); - free_string(t2); - free_string(t1); + ref_push_type_value(n->type); + ref_push_type_value(type); + yytype_report(REPORT_WARNING, + NULL, 0, NULL, + NULL, 0, NULL, + 2, "Soft cast of %O to %O is a noop."); } #else /* !NEW_ARG_CHECK */ if (!check_soft_cast(type, n->type)) { - struct pike_string *t1 = describe_type(type); - struct pike_string *t2 = describe_type(n->type); - yywarning("Soft cast to %S isn't a restriction of %S.", - t1, t2); - free_string(t2); - free_string(t1); + ref_push_type_value(type); + ref_push_type_value(n->type); + yytype_report(REPORT_WARNING, + NULL, 0, NULL, + NULL, 0, NULL, + 2, "Soft cast to %S isn't a restriction of %S."); } /* FIXME: check_soft_cast() is weaker than pike_types_le() * The resulting type should probably be the and between the old @@ -1658,12 +1658,21 @@ node *index_node(node *n, char *node_name, struct pike_string *id) if(Pike_compiler->new_program->flags & PROGRAM_PASS_1_DONE) { if (!exception) { + struct compilation *c = THIS_COMPILATION; if (node_name) { my_yyerror("Index %S not present in module \"%s\".", id, node_name); } else { my_yyerror("Index %S not present in module.", id); } + push_int(REPORT_ERROR); + ref_push_string(c->lex.current_file); + push_int(c->lex.current_line); + push_constant_text("compiler"); + push_constant_text("Indexed module was: %O."); + resolv_constant(n); + safe_apply_current(PC_REPORT_FUN_NUM, 6); + pop_stack(); } }else if (!(Pike_compiler->flags & COMPILATION_FORCE_RESOLVE)) { /* Hope it's there in pass 2 */ @@ -3054,38 +3063,6 @@ static void low_build_function_type(node *n) } } -void yytype_error(const char *msg, struct pike_type *expected_t, - struct pike_type *got_t, unsigned int flags) -{ - if (msg) - { - if (flags & YYTE_IS_WARNING) - yywarning("%s", msg); - else - yyerror(msg); - } - - if (expected_t && got_t) { - yyexplain_nonmatching_types(expected_t, got_t, flags); - } else if (expected_t) { - struct pike_string *s = describe_type(expected_t); - if (flags & YYTE_IS_WARNING) { - yywarning("Expected: %S", s); - } else { - my_yyerror("Expected: %S", s); - } - free_string(s); - } else if (got_t) { - struct pike_string *s = describe_type(got_t); - if (flags & YYTE_IS_WARNING) { - yywarning("Got : %S", s); - } else { - my_yyerror("Got : %S", s); - } - free_string(s); - } -} - static struct pike_string *get_name_of_function(node *n) { struct pike_string *name = NULL; @@ -3253,33 +3230,28 @@ void fix_type_field(node *n) struct pike_type *soft_type = NULL; if (CDR(n) && (CDR(n)->token == F_CONSTANT) && (CDR(n)->u.sval.type == T_TYPE)) { - struct pike_string *t1; - struct pike_string *t2; soft_type = CDR(n)->u.sval.u.type; if ((n->type = soft_cast(soft_type, CAR(n)->type, 0))) { /* Success. */ break; } - t1 = describe_type(soft_type); - t2 = describe_type(CAR(n)->type); - my_yyerror("Soft cast of %S to %S isn't a valid cast.", - t2, t1); - free_string(t2); - free_string(t1); + ref_push_type_value(CAR(n)->type); + ref_push_type_value(soft_type); + yytype_report(REPORT_ERROR, NULL, 0, NULL, NULL, 0, NULL, 2, + "Soft cast of %O to %O isn't a valid cast."); } else { - yytype_error("Soft cast with non-type.", - type_type_string, - CDR(n)->type, 0); + yytype_report(REPORT_ERROR, NULL, 0, type_type_string, + NULL, 0, CDR(n)->type, 0, + "Soft cast with non-type."); } /* Failure: Fall through to the old code. */ #else /* !NEW_ARG_CHECK */ if (!check_soft_cast(old_type, CAR(n)->type)) { - struct pike_string *t1 = describe_type(old_type); - struct pike_string *t2 = describe_type(CAR(n)->type); - yywarning("Soft cast to %S isn't a restriction of %S.", - t1, t2); - free_string(t2); - free_string(t1); + ref_push_type_value(old_type); + ref_push_type_value(CAR(n)->type); + yytype_report(REPORT_ERROR, NULL, 0, NULL, NULL, 0, NULL, 2, + "Soft cast to %S isn't a restriction of %S.", + t1, t2); } /* FIXME: check_soft_cast() is weaker than pike_types_le() * The resulting type should probably be the AND between the old @@ -3362,8 +3334,9 @@ void fix_type_field(node *n) match_types(array_type_string, CDR(n)->type)) || match_types(array_type_string, CADR(n)->type))) && !match_types(CDR(n)->type,CAR(n)->type)) { - yytype_error("Bad type in assignment.", - CDR(n)->type, CAR(n)->type, 0); + yytype_report(REPORT_ERROR, NULL, 0, CDR(n)->type, + NULL, 0, CAR(n)->type, + 0, "Bad type in assignment."); } else { if (c->lex.pragmas & ID_STRICT_TYPES) { struct pike_string *t1 = describe_type(CAR(n)->type); @@ -3441,8 +3414,9 @@ void fix_type_field(node *n) type_b=CDR(n)->type; if(!check_indexing(type_a, type_b, n)) if(!Pike_compiler->catch_level) - yyerror("Indexing on illegal type."); - n->type=index_type(type_a, type_b,n); + yytype_report(REPORT_ERROR, NULL, 0, NULL, NULL, 0, type_b, + 0, "Indexing on illegal type."); + n->type = index_type(type_a, type_b, n); } else { copy_pike_type(n->type, mixed_type_string); } @@ -3468,8 +3442,9 @@ void fix_type_field(node *n) struct pike_type *array_type; MAKE_CONSTANT_TYPE(array_type, tArr(tZero)); if (!pike_types_le(array_type, CAR(n)->type)) { - yytype_error("Bad argument to splice operator.", - array_type, CAR(n)->type, 0); + yytype_report(REPORT_ERROR, NULL, 0, array_type, + NULL, 0, CAR(n)->type, + 0, "Bad argument to splice operator."); } free_type(array_type); /* FIXME: The type field of the splice operator is not yet utilized. @@ -3491,7 +3466,10 @@ void fix_type_field(node *n) type_a=CAR(n)->type; if(!match_types(type_a, array_type_string)) if(!Pike_compiler->catch_level) - yyerror("[*] on non-array."); + yytype_report(REPORT_ERROR, + NULL, 0, array_type_string, + NULL, 0, type_a, + 0, "[*] on non-array."); n->type=index_type(type_a, int_type_string, n); } break; @@ -3512,8 +3490,9 @@ void fix_type_field(node *n) if (!match_types(CAR(n)->type, function_type_string) && !match_types(CAR(n)->type, array_type_string)) { - yytype_error("Calling non function value.", - function_type_string, CAR(n)->type, 0); + yytype_report(REPORT_ERROR, NULL, 0, function_type_string, + NULL, 0, CAR(n)->type, + 0, "Calling non function value."); copy_pike_type(n->type, mixed_type_string); /* print_tree(n); */ @@ -3556,14 +3535,19 @@ void fix_type_field(node *n) copy_pike_type(n->type, mixed_type_string); if ((s = get_first_arg_type(dmalloc_touch(struct pike_type *, f), 0))) { - my_yyerror("Too few arguments to %S (got %d).", name, args); - yytype_error(NULL, s, NULL, 0); + yytype_report(REPORT_ERROR, NULL, 0, s, + NULL, 0, NULL, + 0, "Too few arguments to %S (got %d).", + name, args); free_type(s); - yytype_error("Function type:", CAR(n)->type, NULL, 0); - yytype_error("Remaining type:", f, NULL, 0); + yytype_report(REPORT_ERROR, NULL, 0, NULL, + NULL, 0, CAR(n)->type, + 0, "Function type:"); } else { - my_yyerror("Attempt to call a non function value %S.", name); - yytype_error(NULL, function_type_string, f, 0); + yytype_report(REPORT_ERROR, NULL, 0, function_type_string, + NULL, 0, f, + 0, "Attempt to call a non function value %S.", + name); } free_type(f); break; @@ -3720,8 +3704,7 @@ void fix_type_field(node *n) my_yyerror("Too few arguments to %s.", alternate_name); } } else if (name) { - my_yyerror("Bad argument %d to %S.", - max_correct_args+1, name); + my_yyerror("Bad argument %d to %S.", max_correct_args+1, name); } else { my_yyerror("Bad argument %d to %s.", max_correct_args+1, alternate_name); @@ -3846,9 +3829,10 @@ void fix_type_field(node *n) free_type(call_type); break; } - my_yyerror("Bad arguments to %S.", op_string); - yytype_error(NULL, op_node->type ? op_node->type : mixed_type_string, - call_type, 0); + yytype_report(REPORT_ERROR, NULL, 0, + op_node->type ? op_node->type : mixed_type_string, + NULL, 0, call_type, + 0, "Bad arguments to %S.", op_string); free_node(op_node); free_type(call_type); } @@ -3899,8 +3883,10 @@ void fix_type_field(node *n) if (!match_types(CAR(n)->type, CDR(n)->type)) { if (!match_types(CAR(n)->type, int_type_string) || !match_types(CDR(n)->type, int_type_string)) { - yytype_error("Type mismatch in case range.", - CAR(n)->type, CDR(n)->type, 0); + yytype_report(REPORT_ERROR, + NULL, 0, CAR(n)->type, + NULL, 0, CDR(n)->type, + 0, "Type mismatch in case range."); } } else if ((c->lex.pragmas & ID_STRICT_TYPES) && (CAR(n)->type != CDR(n)->type)) { @@ -3909,14 +3895,18 @@ void fix_type_field(node *n) /* Note that zero should be handled as int(0..0) here. */ if (!(CAR(n)->type == zero_type_string) || !(pike_types_le(CDR(n)->type, int_type_string))) { - yytype_error("Type mismatch in case range.", - CAR(n)->type, CDR(n)->type, YYTE_IS_WARNING); + yytype_report(REPORT_ERROR, + NULL, 0, CAR(n)->type, + NULL, 0, CDR(n)->type, + 0, "Type mismatch in case range."); } } else if (!pike_types_le(CAR(n)->type, CDR(n)->type)) { if (!(CDR(n)->type == zero_type_string) || !(pike_types_le(CAR(n)->type, int_type_string))) { - yytype_error("Type mismatch in case range.", - CDR(n)->type, CAR(n)->type, YYTE_IS_WARNING); + yytype_report(REPORT_WARNING, + NULL, 0, CAR(n)->type, + NULL, 0, CDR(n)->type, + 0, "Type mismatch in case range."); } } } @@ -4010,16 +4000,22 @@ void fix_type_field(node *n) index_type = check_call(foreach_call_type, index_fun_type, 0); if (!index_type) { /* Should not happen. */ - yyerror("Bad iterator type for index in foreach()."); + yytype_report(REPORT_ERROR, + NULL, 0, NULL, + NULL, 0, NULL, + 0, "Bad iterator type for index in foreach()."); } else { if (!pike_types_le(index_type, CADAR(n)->type)) { + int level = REPORT_NOTICE; if (!match_types(CADAR(n)->type, index_type)) { - yytype_error("Type mismatch for index in foreach().", - index_type, CADAR(n)->type, 0); + level = REPORT_ERROR; } else if (c->lex.pragmas & ID_STRICT_TYPES) { - yytype_error("Type mismatch for index in foreach().", - index_type, CADAR(n)->type, YYTE_IS_WARNING); + level = REPORT_WARNING; } + yytype_report(level, + NULL, 0, index_type, + NULL, 0, CADAR(n)->type, + 0, "Type mismatch for index in foreach()."); } free_type(index_type); } @@ -4040,16 +4036,22 @@ void fix_type_field(node *n) value_type = check_call(foreach_call_type, value_fun_type, 0); if (!value_type) { /* Should not happen. */ - yyerror("Bad iterator type for value in foreach()."); + yytype_report(REPORT_ERROR, + NULL, 0, NULL, + NULL, 0, NULL, + 0, "Bad iterator type for value in foreach()."); } else { if (!pike_types_le(value_type, CDDAR(n)->type)) { + int level = REPORT_NOTICE; if (!match_types(CDDAR(n)->type, value_type)) { - yytype_error("Type mismatch for value in foreach().", - value_type, CDDAR(n)->type, 0); + level = REPORT_ERROR; } else if (c->lex.pragmas & ID_STRICT_TYPES) { - yytype_error("Type mismatch for value in foreach().", - value_type, CDDAR(n)->type, YYTE_IS_WARNING); + level = REPORT_WARNING; } + yytype_report(level, + NULL, 0, value_type, + NULL, 0, CDDAR(n)->type, + 0, "Type mismatch for value in foreach()."); } free_type(value_type); } @@ -4062,14 +4064,18 @@ void fix_type_field(node *n) MAKE_CONSTANT_TYPE(array_zero, tArr(tZero)); if (!pike_types_le(array_zero, CAAR(n)->type)) { - yyerror("Bad argument 1 to foreach()."); + yytype_report(REPORT_ERROR, + NULL, 0, array_zero, + NULL, 0, CAAR(n)->type, + 0, "Bad argument 1 to foreach()."); } else { if ((c->lex.pragmas & ID_STRICT_TYPES) && !pike_types_le(CAAR(n)->type, array_type_string)) { - struct pike_string *t = describe_type(CAAR(n)->type); - yywarning("Argument 1 to foreach() is not always an array."); - yywarning("Got: %S", t); - free_string(t); + yytype_report(REPORT_WARNING, + NULL, 0, CAAR(n)->type, + NULL, 0, array_type_string, + 0, + "Argument 1 to foreach() is not always an array."); } if (!CDAR(n)) { @@ -4125,12 +4131,19 @@ void fix_type_field(node *n) if (!(n->type = new_get_return_type(sscanf_type, 0))) { struct pike_type *expected; if ((expected = get_first_arg_type(sscanf_type, 0))) { - my_yyerror("Too few arguments to %S (got %d).", sscanf_name, argno); - yytype_error(NULL, expected, NULL, 0); + yytype_report(REPORT_ERROR, + NULL, 0, expected, + NULL, 0, NULL, + 0, "Too few arguments to %S (got %d).", + sscanf_name, argno); free_type(expected); } else { - my_yyerror("Attempt to call a non function value %S.", sscanf_name); - yytype_error(NULL, function_type_string, sscanf_type, 0); + /* Most likely not reached. */ + yytype_report(REPORT_ERROR, + NULL, 0, function_type_string, + NULL, 0, sscanf_type, + 0, "Attempt to call a non function value %S.", + sscanf_name); } } free_type(sscanf_type); diff --git a/src/las.h b/src/las.h index ff680c2928a1a2a6dc6cfe77c35b25641a1b9da5..6de405f168fd407919950c848574fb345b1abcf5 100644 --- a/src/las.h +++ b/src/las.h @@ -2,7 +2,7 @@ || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. -|| $Id: las.h,v 1.78 2008/02/05 23:20:32 mast Exp $ +|| $Id: las.h,v 1.79 2008/05/24 15:14:12 grubba Exp $ */ #ifndef LAS_H @@ -22,11 +22,6 @@ typedef void (*c_fun)(INT32); struct compiler_frame; /* Avoid gcc warning. */ -void yytype_error(const char *msg, struct pike_type *expected_t, - struct pike_type *got_t, unsigned int flags); -void low_yyerror(struct pike_string *str); -PMOD_EXPORT void yyerror(const char *s); -static void yyerror_reserved(const char *keyword); int islocal(struct pike_string *str); int low_add_local_name(struct compiler_frame *frame, struct pike_string *str, diff --git a/src/modules/sprintf/sprintf.c b/src/modules/sprintf/sprintf.c index cc972e884882f6830b9a5a6b750ed9be1a8682e1..95937cf278df96163b6f9e2cca6b6f1f22bcd428 100644 --- a/src/modules/sprintf/sprintf.c +++ b/src/modules/sprintf/sprintf.c @@ -2,7 +2,7 @@ || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. -|| $Id: sprintf.c,v 1.152 2008/05/21 21:59:07 grubba Exp $ +|| $Id: sprintf.c,v 1.153 2008/05/24 15:14:13 grubba Exp $ */ /* TODO: use ONERROR to cleanup fsp */ @@ -311,7 +311,6 @@ #include "cyclic.h" #include "module.h" #include "pike_float.h" -#include "pike_compiler.h" #include <ctype.h> #include "config.h" @@ -1870,14 +1869,6 @@ static int push_sprintf_argument_types(PCHARP format, ptrdiff_t format_len, PCHARP a,begin; PCHARP format_end=ADD_PCHARP(format,format_len); - struct compilation *c = THIS_COMPILATION; - int severity_level = REPORT_ERROR; - - if ((c->major != -1) && - ((c->major < 7) || ((c->major == 7) && (c->minor < 7)))) { - /* Compat mode: Pike 7.6 or earlier. */ - severity_level = REPORT_WARNING; - } check_c_stack(500); @@ -1907,12 +1898,12 @@ static int push_sprintf_argument_types(PCHARP format, ptrdiff_t format_len, default: if(EXTRACT_PCHARP(a) < 256 && isprint(EXTRACT_PCHARP(a))) { - yyreport(severity_level, "type_check", - "Error in format string, %c is not a format.", + yyreport(REPORT_ERROR, type_check_system_string, + 0, "Error in format string, %c is not a format.", EXTRACT_PCHARP(a)); }else{ - yyreport(severity_level, "type_check", - "Error in format string, U%08x is not a format.", + yyreport(REPORT_ERROR, type_check_system_string, + 0, "Error in format string, U%08x is not a format.", EXTRACT_PCHARP(a)); } num_snurkel = 0; @@ -1941,8 +1932,8 @@ static int push_sprintf_argument_types(PCHARP format, ptrdiff_t format_len, { case 0: case 1: if(tmp < 0) { - yyreport(severity_level, "type_check", - "Illegal width %d.", tmp); + yyreport(REPORT_ERROR, type_check_system_string, + 0, "Illegal width %d.", tmp); } case 2: case 3: case 4: break; } @@ -1958,16 +1949,16 @@ static int push_sprintf_argument_types(PCHARP format, ptrdiff_t format_len, case '/': column |= ROUGH_LINEBREAK; if( column & LINEBREAK ) { - yyreport(severity_level, "type_check", - "Can not use both the modifiers / and =."); + yyreport(REPORT_ERROR, type_check_system_string, + 0, "Can not use both the modifiers / and =."); } continue; case '=': column |= LINEBREAK; if( column & ROUGH_LINEBREAK ) { - yyreport(severity_level, "type_check", - "Can not use both the modifiers / and =."); + yyreport(REPORT_ERROR, type_check_system_string, + 0, "Can not use both the modifiers / and =."); } continue; @@ -1984,8 +1975,8 @@ static int push_sprintf_argument_types(PCHARP format, ptrdiff_t format_len, for(INC_PCHARP(a,1);INDEX_PCHARP(a,tmp)!='\'';tmp++) { if(COMPARE_PCHARP(a,>=,format_end)) { - yyreport(severity_level, "type_check", - "Unfinished pad string in format string."); + yyreport(REPORT_ERROR, type_check_system_string, + 0, "Unfinished pad string in format string."); } } INC_PCHARP(a,tmp); @@ -2002,8 +1993,8 @@ static int push_sprintf_argument_types(PCHARP format, ptrdiff_t format_len, /* FIXME: !!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ return 0; /* FAILURE! */ if(!lastarg) { - yyreport(severity_level, "type_check", - "No last argument."); + yyreport(REPORT_ERROR, type_check_system_string, + 0, "No last argument."); } arg=lastarg; continue; @@ -2019,13 +2010,13 @@ static int push_sprintf_argument_types(PCHARP format, ptrdiff_t format_len, } else tmp=STRTOL_PCHARP(a,&a,10); if(EXTRACT_PCHARP(a)!=']') { - yyreport(severity_level, "type_check", - "Expected ] in format string, not %c.", + yyreport(REPORT_ERROR, type_check_system_string, + 0, "Expected ] in format string, not %c.", EXTRACT_PCHARP(a)); } if(tmp >= num_arg) { - yyreport(severity_level, "type_check", - "Not enough arguments to [%d].", tmp); + yyreport(REPORT_ERROR, type_check_system_string, + 0, "Not enough arguments to [%d].", tmp); } /* arg = argp+tmp; */ continue; @@ -2039,8 +2030,8 @@ static int push_sprintf_argument_types(PCHARP format, ptrdiff_t format_len, { if (!INDEX_PCHARP(a,e) && !COMPARE_PCHARP(ADD_PCHARP(a,e),<,format_end)) { - yyreport(severity_level, "type_check", - "Missing %} in format string."); + yyreport(REPORT_ERROR, type_check_system_string, + 0, "Missing %%} in format string."); break; } else if(INDEX_PCHARP(a,e)=='%') { switch(INDEX_PCHARP(a,e+1)) @@ -2232,14 +2223,6 @@ void f___handle_sprintf_format(INT32 args) struct pike_string *fmt; int found = 0; int fmt_count; - struct compilation *c = THIS_COMPILATION; - int severity_level = REPORT_ERROR; - - if ((c->major != -1) && - ((c->major < 7) || ((c->major == 7) && (c->minor < 7)))) { - /* Compat mode: Pike 7.6 or earlier. */ - severity_level = REPORT_WARNING; - } #if 0 fprintf(stderr, "__handle_sprintf_format()\n"); @@ -2307,11 +2290,6 @@ void f___handle_sprintf_format(INT32 args) res = pop_unfinished_type(); pop_n_elems(args); push_type_value(res); - if (severity_level <= REPORT_WARNING) { - /* Disable further checks in compat mode. */ - pop_stack(); - push_undefined(); - } return; } else { /* Join the argument types into the array. */ @@ -2355,11 +2333,6 @@ void f___handle_sprintf_format(INT32 args) res = pop_unfinished_type(); pop_n_elems(args); push_type_value(res); - if (severity_level <= REPORT_WARNING) { - /* Disable further checks in compat mode. */ - pop_stack(); - push_undefined(); - } } else { /* No marker found. */ #if 0 diff --git a/src/pike_compiler.h b/src/pike_compiler.h index ec7c901443705d36b13839eab64e635a223a975f..3f63d9a5e31dfba1a9c6ce7c6a5da64c20fa8680 100644 --- a/src/pike_compiler.h +++ b/src/pike_compiler.h @@ -2,7 +2,7 @@ || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. -|| $Id: pike_compiler.h,v 1.13 2008/05/18 15:36:23 grubba Exp $ +|| $Id: pike_compiler.h,v 1.14 2008/05/24 15:14:12 grubba Exp $ */ #ifndef PIKE_COMPILER_H @@ -56,12 +56,6 @@ struct compilation #define COMPILER_BUSY 1 /* The compiler is busy compiling. */ #define COMPILER_DONE 2 /* The is finished compiling. */ -/* Report levels */ -#define REPORT_NOTICE 0 /* FYI. */ -#define REPORT_WARNING 1 /* Compiler warning. */ -#define REPORT_ERROR 2 /* Compilation error. */ -#define REPORT_FATAL 3 /* Unrecoverable error. */ - /* CompilerEnvironment function numbers. */ #define CE_REPORT_FUN_NUM 0 #define CE_COMPILE_FUN_NUM 1 diff --git a/src/pike_types.c b/src/pike_types.c index f3dfb3740fd8b0677963dff4733ae3f43f0ec496..0e53035447c34cf745df45ba4316bc2f681ba023 100644 --- a/src/pike_types.c +++ b/src/pike_types.c @@ -2,7 +2,7 @@ || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. -|| $Id: pike_types.c,v 1.336 2008/05/18 15:44:51 grubba Exp $ +|| $Id: pike_types.c,v 1.337 2008/05/24 15:14:12 grubba Exp $ */ #include "global.h" @@ -4529,7 +4529,7 @@ static int low_get_return_type(struct pike_type *a, struct pike_type *b) #if 0 if ((c->lex.pragmas & ID_STRICT_TYPES) && !low_pike_types_le(a, b, 0, 0)) { - yywarning("Type mismatch"); + yyreport_type(REPORT_WARNING, NULL, 0, b, NULL, 0, a, 0, "Type mismatch"); } #endif /* 0 */ switch(a->type) @@ -4925,22 +4925,18 @@ static struct pike_type *debug_low_range_type(struct pike_type *t, /* Check that the index types are compatible with int. */ { if (index1_type && !low_match_types(int_type_string, index1_type, 0)) { - struct pike_string *s = describe_type(t); - yywarning("Bad argument 1 to range operator on %s.", - s->str); - free_string(s); - yyexplain_nonmatching_types(int_type_string, index1_type, - YYTE_IS_WARNING); + ref_push_type_value(t); + yytype_report(REPORT_WARNING, NULL, 0, int_type_string, + NULL, 0, index1_type, + 1, "Bad argument 1 to range operator on %O."); /* Bad index1 type. */ return 0; } if (index2_type && !low_match_types(int_type_string, index2_type, 0)) { - struct pike_string *s = describe_type(t); - yywarning("Bad argument 2 to range operator on %s.", - s->str); - free_string(s); - yyexplain_nonmatching_types(int_type_string, index2_type, - YYTE_IS_WARNING); + ref_push_type_value(t); + yytype_report(REPORT_WARNING, NULL, 0, int_type_string, + NULL, 0, index2_type, + 1, "Bad argument 2 to range operator on %O."); /* Bad index2 type. */ return 0; } @@ -4979,7 +4975,8 @@ struct pike_type *range_type(struct pike_type *type, clear_markers(); t = low_range_type(type, index1_type, index2_type); if(!t) { - yyerror("Invalid range operation."); + yytype_report(REPORT_ERROR, NULL, 0, NULL, NULL, 0, NULL, + 0, "Invalid range operation."); copy_pike_type(t, type); } return t; @@ -5318,24 +5315,21 @@ struct pike_type *check_call(struct pike_type *args, { if (strict) { if (!strict_check_call(type, args)) { - struct pike_string *type_t = describe_type(type); struct pike_type *func_zero_type; MAKE_CONSTANT_TYPE(func_zero_type, tFuncV(tNone,tZero,tMix)); if (!low_pike_types_le(type, func_zero_type, 0, 0)) { - yywarning("Calling non-function value."); - yywarning("Type called: %s", type_t->str); + yytype_report(REPORT_WARNING, NULL, 0, function_type_string, + NULL, 0, type, + 0, "Calling non-function value."); } else { - struct pike_string *arg_t = describe_type(args); - yywarning("Arguments not strictly compatible."); - yywarning("Expected: %s", type_t->str); - yywarning("Got : %s", arg_t->str); - free_string(arg_t); + yytype_report(REPORT_WARNING, NULL, 0, type, + NULL, 0, args, + 0, "Arguments not strictly compatible."); } free_type(func_zero_type); - free_string(type_t); } } return pop_unfinished_type(); @@ -6799,14 +6793,12 @@ struct pike_type *new_check_call(struct pike_string *fun_name, !(flags & CALL_ARG_LVALUE)){ if (!(tmp = low_new_check_call(fun_type, args->type, flags|CALL_STRICT, sval))) { - yywarning("Type mismatch in argument %d to %S.", - *argno, fun_name); - if ((tmp = get_first_arg_type(fun_type, 0))) { - yytype_error(NULL, tmp, args->type, YYTE_IS_WARNING); - free_type(tmp); - } else { - yytype_error(NULL, NULL, args->type, YYTE_IS_WARNING); - } + tmp = get_first_arg_type(fun_type, 0); + yytype_report(REPORT_WARNING, NULL, 0, tmp, + NULL, 0, args->type, + 0, "Type mismatch in argument %d to %S.", + *argno, fun_name); + if (tmp) free_type(tmp); } else { free_type(tmp); } @@ -6823,9 +6815,8 @@ struct pike_type *new_check_call(struct pike_string *fun_name, fprintf(stderr, " Bad argument.\n"); } #endif /* PIKE_DEBUG */ - my_yyerror("Bad argument %d to %S.", - *argno, fun_name); - yytype_error(NULL, tmp, args->type, 0); + yytype_report(REPORT_ERROR, NULL, 0, tmp, NULL, 0, args->type, + 0, "Bad argument %d to %S.", *argno, fun_name); /* Try advancing with the suggested type, so that we can check * the rest of the arguments. @@ -6855,9 +6846,10 @@ struct pike_type *new_check_call(struct pike_string *fun_name, fprintf(stderr, " Too many arguments.\n"); } #endif /* PIKE_DEBUG */ - my_yyerror("Too many arguments to %S (expected %d arguments).", - fun_name, *argno - 1); - yytype_error(NULL, NULL, args->type, 0); + yytype_report(REPORT_ERROR, NULL, 0, NULL, + NULL, 0, args->type, + 0, "Too many arguments to %S (expected %d arguments).", + fun_name, *argno - 1); } free_type(fun_type); return NULL; @@ -7248,9 +7240,13 @@ int type_may_overload(struct pike_type *type, int lfun) } -void yyexplain_nonmatching_types(struct pike_type *type_a, - struct pike_type *type_b, - int flags) +void yyexplain_nonmatching_types(int severity_level, + struct pike_string *a_file, + INT32 a_line, + struct pike_type *type_a, + struct pike_string *b_file, + INT32 b_line, + struct pike_type *type_b) { DECLARE_CYCLIC(); @@ -7267,18 +7263,13 @@ void yyexplain_nonmatching_types(struct pike_type *type_a, #endif /* 0 */ { struct pike_string *s1, *s2; - s1 = describe_type(type_a); - s2 = describe_type(type_b); - if(flags & YYTE_IS_WARNING) - { - yywarning("Expected: %S", s1); - yywarning("Got : %S", s2); - }else{ - my_yyerror("Expected: %S", s1); - my_yyerror("Got : %S", s2); - } - free_string(s1); - free_string(s2); + + ref_push_type_value(type_a); + yytype_report(severity_level, NULL, 0, NULL, a_file, a_line, NULL, + 1, "Expected: %O"); + ref_push_type_value(type_b); + yytype_report(severity_level, NULL, 0, NULL, b_file, b_line, NULL, + 1, "Got : %O"); } /* Protect against circularities. */ @@ -7290,9 +7281,9 @@ void yyexplain_nonmatching_types(struct pike_type *type_a, if(implements_a && implements_b) { if (implements_mode) { - yyexplain_not_implements(implements_a, implements_b, flags); + yyexplain_not_implements(severity_level, implements_a, implements_b); } else { - yyexplain_not_compatible(implements_a, implements_b, flags); + yyexplain_not_compatible(severity_level, implements_a, implements_b); } } END_CYCLIC(); diff --git a/src/pike_types.h b/src/pike_types.h index 7c011edeea1fae19efe14065e3ca3d1e3cdeb9de..ab612e5ffc19580862f4e25f0e9022431d71825b 100644 --- a/src/pike_types.h +++ b/src/pike_types.h @@ -2,7 +2,7 @@ || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. -|| $Id: pike_types.h,v 1.117 2008/05/17 22:48:33 grubba Exp $ +|| $Id: pike_types.h,v 1.118 2008/05/24 15:14:12 grubba Exp $ */ #ifndef PIKE_TYPES_H @@ -284,9 +284,13 @@ void gc_mark_type_as_referenced(struct pike_type *t); void gc_check_type (struct pike_type *t); void gc_check_all_types (void); int type_may_overload(struct pike_type *type, int lfun); -void yyexplain_nonmatching_types(struct pike_type *type_a, - struct pike_type *type_b, - int flags); +void yyexplain_nonmatching_types(int severity_level, + struct pike_string *a_file, + INT32 a_line, + struct pike_type *type_a, + struct pike_string *b_file, + INT32 b_line, + struct pike_type *type_b); struct pike_type *debug_make_pike_type(const char *t); struct pike_string *type_to_string(struct pike_type *t); int pike_type_allow_premature_toss(struct pike_type *type); diff --git a/src/program.c b/src/program.c index d322f4ba5ad93bf97be5c69d604a91b6cb41c8e6..ecaa3b3015911ea2f2b9c36b48e8b21ad8abf68b 100644 --- a/src/program.c +++ b/src/program.c @@ -2,7 +2,7 @@ || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. -|| $Id: program.c,v 1.701 2008/05/22 20:13:19 mast Exp $ +|| $Id: program.c,v 1.702 2008/05/24 15:14:12 grubba Exp $ */ #include "global.h" @@ -107,6 +107,10 @@ struct pike_string *this_program_string; static struct pike_string *this_string, *this_function_string; static struct pike_string *UNDEFINED_string; +/* Common compiler subsystems */ +struct pike_string *parser_system_string; +struct pike_string *type_check_system_string; + const char *const lfun_names[] = { "__INIT", "create", @@ -2076,11 +2080,12 @@ int override_identifier (struct reference *new_ref, struct pike_string *name) if ((Pike_compiler->compiler_pass == 2) && !pike_types_le(ID_FROM_PTR(Pike_compiler->new_program, new_ref)->type, sub_id->type)) { - yywarning("Type mismatch when overloading function %S.", name); - yyexplain_nonmatching_types(sub_id->type, - ID_FROM_PTR(Pike_compiler->new_program, - new_ref)->type, - YYTE_IS_WARNING); + yytype_report(REPORT_WARNING, + NULL, 0, sub_id->type, + NULL, 0, ID_FROM_PTR(Pike_compiler->new_program, + new_ref)->type, + 0, "Type mismatch when overloading function %S.", + name); } } else { struct identifier *new_id; @@ -2095,9 +2100,10 @@ int override_identifier (struct reference *new_ref, struct pike_string *name) (new_id->run_time_type == PIKE_T_INT) && (IDENTIFIER_IS_CONSTANT(sub_id->identifier_flags) || match_types(sub_id->type, new_id->type)))) { - yywarning("Type mismatch when overloading %S.", name); - yyexplain_nonmatching_types(sub_id->type, new_id->type, - YYTE_IS_WARNING); + yytype_report(REPORT_WARNING, + NULL, 0, sub_id->type, + NULL, 0, new_id->type, + 0, "Type mismatch when overloading %S.", name); } } } @@ -2197,9 +2203,10 @@ void fixate_program(void) (funp->id_flags & ID_USED)) { /* Verify that the types are compatible. */ if (!pike_types_le(funb->type, fun->type)) { - yywarning("Type mismatch when overloading %S.", fun->name); - yyexplain_nonmatching_types(fun->type, funb->type, - YYTE_IS_WARNING); + yytype_report(REPORT_WARNING, NULL, 0, fun->type, + NULL, 0, funb->type, + 0, "Type mismatch when overloading %S.", + fun->name); } } funp->inherit_offset = funpb->inherit_offset; @@ -2211,9 +2218,10 @@ void fixate_program(void) (funpb->id_flags & ID_USED)) { /* Verify that the types are compatible. */ if (!pike_types_le(fun->type, funb->type)) { - yywarning("Type mismatch when overloading %S.", fun->name); - yyexplain_nonmatching_types(funb->type, fun->type, - YYTE_IS_WARNING); + yytype_report(REPORT_WARNING, NULL, 0, funb->type, + NULL, 0, fun->type, + 0, "Type mismatch when overloading %S.", + fun->name); } } funpb->inherit_offset = funp->inherit_offset; @@ -4889,7 +4897,7 @@ int define_variable(struct pike_string *name, #endif if(type == void_type_string) - yyerror("Variables can't be of type void"); + yyerror("Variables can't be of type void."); n = isidentifier(name); @@ -4938,21 +4946,16 @@ int define_variable(struct pike_string *name, if(ID_FROM_INT(Pike_compiler->new_program, n)->type != type && !pike_types_le(type, ID_FROM_INT(Pike_compiler->new_program, n)->type)) { + int level = REPORT_WARNING; if (!match_types(ID_FROM_INT(Pike_compiler->new_program, n)->type, type)) { - my_yyerror("Illegal to redefine inherited variable %S " - "with different type.", name); - yytype_error(NULL, - ID_FROM_INT(Pike_compiler->new_program, n)->type, - type, 0); - return n; - } else { - yywarning("Redefining inherited variable %S " - "with different type.", name); - yytype_error(NULL, - ID_FROM_INT(Pike_compiler->new_program, n)->type, - type, YYTE_IS_WARNING); + level = REPORT_ERROR; } + yytype_report(level, NULL, 0, + ID_FROM_INT(Pike_compiler->new_program, n)->type, + NULL, 0, type, 0, + "Illegal to redefine inherited variable %S " + "with different type.", name); } @@ -4968,11 +4971,11 @@ int define_variable(struct pike_string *name, PIKE_T_MIXED) && (ID_FROM_INT(Pike_compiler->new_program, n)->run_time_type != compile_type_to_runtime_type(type))) { - my_yyerror("Illegal to redefine inherited variable %S " - "with different type.", name); - yytype_error(NULL, - ID_FROM_INT(Pike_compiler->new_program, n)->type, - type, 0); + yytype_report(REPORT_ERROR, NULL, 0, + ID_FROM_INT(Pike_compiler->new_program, n)->type, + NULL, 0, type, 0, + "Illegal to redefine inherited variable %S " + "with different type.", name); return n; } @@ -5468,15 +5471,15 @@ INT32 define_function(struct pike_string *name, } #endif /* PIKE_DEBUG */ if (!pike_types_le(type, lfun_type->u.type)) { + int level = REPORT_NOTICE; if (!match_types(type, lfun_type->u.type)) { - my_yyerror("Type mismatch for callback function %S:", name); - yytype_error(NULL, lfun_type->u.type, type, 0); - Pike_fatal("Type mismatch!\n"); + level = REPORT_ERROR; } else if (c->lex.pragmas & ID_STRICT_TYPES) { - yywarning("Type mismatch for callback function %S:", name); - yytype_error(NULL, lfun_type->u.type, type, - YYTE_IS_WARNING); + level = REPORT_WARNING; } + yytype_report(level, NULL, 0, lfun_type->u.type, + NULL, 0, type, 0, + "Type mismatch for callback function %S:", name); } } else if (((name->len > 3) && (index_shared_string(name, 0) == '`') && @@ -5513,13 +5516,15 @@ INT32 define_function(struct pike_string *name, /* We got a getter or a setter. */ struct reference *ref; if (!pike_types_le(type, gs_type)) { + int level = REPORT_NOTICE; if (!match_types(type, gs_type)) { - my_yyerror("Type mismatch for callback function %S:", name); - yytype_error(NULL, gs_type, type, 0); + level = REPORT_ERROR; } else if (c->lex.pragmas & ID_STRICT_TYPES) { - yywarning("Type mismatch for callback function %S:", name); - yytype_error(NULL, gs_type, type, YYTE_IS_WARNING); + level = REPORT_WARNING; } + yytype_report(level, NULL, 0, gs_type, + NULL, 0, type, 0, + "Type mismatch for callback function %S:", name); } i = isidentifier(symbol); if ((i >= 0) && @@ -5621,8 +5626,10 @@ INT32 define_function(struct pike_string *name, if(!match_types(type, funp->type)) { if (!(flags & ID_VARIANT)) { - my_yyerror("Prototype doesn't match for function %S.", name); - yytype_error(NULL, funp->type, type, 0); + yytype_report(REPORT_ERROR, NULL, 0, + funp->type, + NULL, 0, type, 0, + "Prototype doesn't match for function %S.", name); } } } @@ -6869,25 +6876,181 @@ PMOD_EXPORT struct pike_string *low_get_function_line (struct object *o, return NULL; } -/* FIXME: Consider converting these to using va_yyreport(). */ - -PMOD_EXPORT void va_yyerror(const char *fmt, va_list args) +/* Main entry point for compiler messages originating from + * C-code. + * + * Sends the message along to PikeCompiler()->report(). + * + * NOTE: The format string fmt (and vargs) is only formatted with + * string_builder_vsprintf() if the number of extra + * Pike stack arguments (args) is zero. + */ +PMOD_EXPORT void va_yyreport(int severity_level, + struct pike_string *file, INT32 line, + struct pike_string *system, INT32 args, + const char *fmt, va_list vargs) { + struct compilation *c = MAYBE_THIS_COMPILATION; struct string_builder s; - struct pike_string *tmp; - init_string_builder(&s, 0); - string_builder_vsprintf(&s, fmt, args); - tmp = finish_string_builder(&s); - low_yyerror(tmp); - free_string(tmp); + struct pike_string *msg; + + if (!c) return; /* No compiler context. */ + + STACK_LEVEL_START(args); + +#ifdef PIKE_DEBUG + if(Pike_interpreter.recoveries && Pike_sp-Pike_interpreter.evaluator_stack < Pike_interpreter.recoveries->stack_pointer) + Pike_fatal("Stack error (underflow)\n"); +#endif + + /* Convert type errors to warnings in non-strict compat mode. */ + if ((system == type_check_system_string) && + (severity_level == REPORT_ERROR) && + (c->major != -1) && + !(c->lex.pragmas & ID_STRICT_TYPES) && + ((c->major < PIKE_MAJOR_VERSION) || + ((c->major == PIKE_MAJOR_VERSION) && + (c->minor < PIKE_MINOR_VERSION)))) { + severity_level = REPORT_WARNING; + } + + /* If we have parse errors we might get erroneous warnings, + * so don't print them. + * This has the additional benefit of making it easier to + * visually locate the actual error message. + */ + if ((severity_level <= REPORT_WARNING) && + Pike_compiler->num_parse_error) { + return; + } + + if (severity_level >= REPORT_ERROR) { + if (Pike_compiler->num_parse_error > 20) return; + Pike_compiler->num_parse_error++; + cumulative_parse_error++; + } + + push_int(severity_level); + ref_push_string(file?file:c->lex.current_file); + push_int(line?line:c->lex.current_line); + ref_push_string(system); + if (args) { + int i = args; + push_text(fmt); + /* Copy the arguments. */ + while (i--) { + push_svalue(Pike_sp-(args+5)); + } + } else { + init_string_builder(&s, 0); + string_builder_vsprintf(&s, fmt, vargs); + push_string(finish_string_builder(&s)); + } + + safe_apply_current(PC_REPORT_FUN_NUM, args + 5); + pop_stack(); + if (args) pop_n_elems(args); + STACK_LEVEL_DONE(0); +} + +PMOD_EXPORT void low_yyreport(int severity_level, + struct pike_string *file, INT32 line, + struct pike_string *system, + INT32 args, const char *fmt, ...) +{ + va_list vargs; + + va_start(vargs,fmt); + va_yyreport(severity_level, file, line, system, args, fmt, vargs); + va_end(vargs); +} + +PMOD_EXPORT void yyreport(int severity_level, struct pike_string *system, + INT32 args, const char *fmt, ...) +{ + va_list vargs; + + va_start(vargs,fmt); + va_yyreport(severity_level, NULL, 0, system, args, fmt, vargs); + va_end(vargs); } +PMOD_EXPORT void yywarning(char *fmt, ...) +{ + va_list vargs; + + va_start(vargs,fmt); + va_yyreport(REPORT_WARNING, NULL, 0, parser_system_string, 0, fmt, vargs); + va_end(vargs); +} + +/* FIXME: Consider converting these to using va_yyreport(). */ + PMOD_EXPORT void my_yyerror(const char *fmt,...) { - va_list args; - va_start(args,fmt); - va_yyerror (fmt, args); - va_end(args); + va_list vargs; + va_start(vargs,fmt); + va_yyreport(REPORT_ERROR, NULL, 0, parser_system_string, 0, fmt, vargs); + va_end(vargs); +} + +PMOD_EXPORT void yyerror(const char *str) +{ + my_yyerror("%s", str); +} + +/* Main entry point for errors from the type-checking subsystems. + * + * The message (if any) will be formatted for the same source + * position as the got_t. + * + * The expect_t will be formatted for the same position as the got_t + * if there's no expected_file/expected_line. + * + * The got_t will be formatted for the current lex position if there's + * no got_file/got_line. + */ +void yytype_report(int severity_level, + struct pike_string *expected_file, INT32 expected_line, + struct pike_type *expected_t, + struct pike_string *got_file, INT32 got_line, + struct pike_type *got_t, + INT32 args, const char *fmt, ...) +{ + if (fmt) + { + va_list vargs; + va_start(vargs, fmt); + va_yyreport(severity_level, got_file, got_line, type_check_system_string, + args, fmt, vargs); + va_end(vargs); + } + + if (expected_t && got_t) { + yyexplain_nonmatching_types(severity_level, + expected_file?expected_file:got_file, + expected_line?expected_line:got_line, + expected_t, + got_file, got_line, got_t); + } else if (expected_t) { + ref_push_type_value(expected_t); + low_yyreport(severity_level, + expected_file?expected_file:got_file, + expected_line?expected_line:got_line, + type_check_system_string, + 1, "Expected: %O."); + } else if (got_t) { + ref_push_type_value(got_t); + low_yyreport(severity_level, got_file, got_line, type_check_system_string, + 1, "Got : %O"); + } +} + +void yytype_error(const char *msg, struct pike_type *expected_t, + struct pike_type *got_t, unsigned int flags) +{ + yytype_report((flags & YYTE_IS_WARNING)?REPORT_WARNING:REPORT_ERROR, + NULL, 0, expected_t, NULL, 0, got_t, 0, "%s", msg); } struct pike_string *format_exception_for_error_msg (struct svalue *thrown) @@ -6923,7 +7086,8 @@ void handle_compile_exception (const char *yyerror_fmt, ...) if (yyerror_fmt) { va_list args; va_start (args, yyerror_fmt); - va_yyerror (yyerror_fmt, args); + va_yyreport(REPORT_ERROR, NULL, 0, parser_system_string, 0, + yyerror_fmt, args); va_end (args); } @@ -6934,8 +7098,8 @@ void handle_compile_exception (const char *yyerror_fmt, ...) if (SAFE_IS_ZERO(sp-1)) { struct pike_string *s = format_exception_for_error_msg (&thrown); if (s) { - low_yyerror(s); - free_string (s); + push_string(s); + yyreport(REPORT_ERROR, parser_system_string, 1, "%s"); } } @@ -7257,6 +7421,7 @@ static void f_compilation_env_report(INT32 args) INT_TYPE linenumber; struct pike_string *subsystem; struct pike_string *message; + if (args > 5) { f_sprintf(args - 4); args = 5; @@ -7947,7 +8112,7 @@ static void f_compilation_report(INT32 args) int fun = -1; /* FIXME: get_all_args() ought to have a marker - * indicating that accept more arguments... + * indicating that we accept more arguments... */ get_all_args("report", args, "%d", &level); @@ -9378,6 +9543,9 @@ void init_program(void) MAKE_CONST_STRING(this_string,"this"); MAKE_CONST_STRING(UNDEFINED_string,"UNDEFINED"); + MAKE_CONST_STRING(parser_system_string, "parser"); + MAKE_CONST_STRING(type_check_system_string, "type_check"); + lfun_ids = allocate_mapping(NUM_LFUNS); lfun_types = allocate_mapping(NUM_LFUNS); for (i=0; i < NELEM(lfun_names); i++) { @@ -10141,56 +10309,6 @@ int find_child(struct program *parent, struct program *child) } #endif /* 0 */ -void va_yyreport(int severity_level, const char *system, - const char *fmt, va_list args) -{ - struct compilation *c = MAYBE_THIS_COMPILATION; - struct string_builder s; - struct pike_string *msg; - - if (!c) return; /* No compiler context. */ - - /* If we have parse errors we might get erroneous warnings, - * so don't print them. - * This has the additional benefit of making it easier to - * visually locate the actual error message. - */ - if ((severity_level <= REPORT_WARNING) && - Pike_compiler->num_parse_error) { - return; - } - - init_string_builder(&s, 0); - string_builder_vsprintf(&s, fmt, args); - msg = finish_string_builder(&s); - - push_int(severity_level); - ref_push_string(c->lex.current_file); - push_int(c->lex.current_line); - push_text(system); - push_string(msg); - safe_apply_current(PC_REPORT_FUN_NUM, 5); - pop_stack(); -} - -void yyreport(int severity_level, const char *system, const char *fmt, ...) -{ - va_list args; - - va_start(args,fmt); - va_yyreport(severity_level, system, fmt, args); - va_end(args); -} - -void yywarning(char *fmt, ...) -{ - va_list args; - - va_start(args,fmt); - va_yyreport(REPORT_WARNING, "parse", fmt, args); - va_end(args); -} - /* returns 1 if a implements b */ @@ -10373,7 +10491,8 @@ PMOD_EXPORT int is_compatible(struct program *a, struct program *b) } /* Explains why a is not compatible with b */ -void yyexplain_not_compatible(struct program *a, struct program *b, int flags) +void yyexplain_not_compatible(int severity_level, + struct program *a, struct program *b) { int e; struct pike_string *s=findstring("__INIT"); @@ -10420,30 +10539,13 @@ void yyexplain_not_compatible(struct program *a, struct program *b, int flags) if(((bid->run_time_type != PIKE_T_INT) || (ID_FROM_INT(a, i)->run_time_type != PIKE_T_INT)) && !match_types(ID_FROM_INT(a,i)->type, bid->type)) { - if (flags & YYTE_IS_WARNING) { - push_int(REPORT_WARNING); - push_int(REPORT_WARNING); - } else { - push_int(REPORT_ERROR); - push_int(REPORT_ERROR); - } - ref_push_string(a_file); - push_int(a_line); - push_constant_text("type_check"); - push_constant_text("Identifier %s in %O is incompatible"); ref_push_string(bid->name); ref_push_program(a); - safe_apply_current2(PC_REPORT_FUN_NUM, 7, "report"); - pop_stack(); - ref_push_string(b_file); - push_int(b_line); - push_constant_text("type_check"); - push_constant_text("with identifier %s in %O"); - ref_push_string(bid->name); ref_push_program(b); - safe_apply_current2(PC_REPORT_FUN_NUM, 7, "report"); - pop_stack(); - yytype_error(NULL, ID_FROM_INT(a,i)->type, bid->type, flags); + yytype_report(severity_level, + a_file, a_line, ID_FROM_INT(a, i)->type, + b_file, b_line, bid->type, 3, + "Identifier %s in %O is incompatible with the same in %O."); } } free_string(b_file); @@ -10453,10 +10555,15 @@ void yyexplain_not_compatible(struct program *a, struct program *b, int flags) } /* Explains why a does not implement b */ -void yyexplain_not_implements(struct program *a, struct program *b, int flags) +void yyexplain_not_implements(int severity_level, + struct program *a, struct program *b) { int e; struct pike_string *s=findstring("__INIT"); + INT32 a_line = 0; + INT32 b_line = 0; + struct pike_string *a_file; + struct pike_string *b_file; DECLARE_CYCLIC(); if (BEGIN_CYCLIC(a, b)) { @@ -10465,6 +10572,9 @@ void yyexplain_not_implements(struct program *a, struct program *b, int flags) } SET_CYCLIC_RET(1); + a_file = get_program_line(a, &a_line); + b_file = get_program_line(b, &b_line); + for(e=0;e<b->num_identifier_references;e++) { struct identifier *bid; @@ -10477,25 +10587,31 @@ void yyexplain_not_implements(struct program *a, struct program *b, int flags) if (i == -1) { if (b->identifier_references[e].id_flags & (ID_OPTIONAL)) continue; /* It's ok... */ - if(flags & YYTE_IS_WARNING) - yywarning("Missing identifier %S.", bid->name); - else - my_yyerror("Missing identifier %S.", bid->name); + yytype_report(severity_level, + b_file, b_line, bid->type, + a_file, a_line, NULL, + 0, "Missing identifier %S.", bid->name); continue; } if (!pike_types_le(bid->type, ID_FROM_INT(a, i)->type)) { if(!match_types(ID_FROM_INT(a,i)->type, bid->type)) { - my_yyerror("Type of identifier %S does not match.", bid->name); - yytype_error(NULL, ID_FROM_INT(a,i)->type, bid->type, 0); + yytype_report(severity_level, + b_file, b_line, bid->type, + a_file, a_line, ID_FROM_INT(a, i)->type, + 0, "Type of identifier %S does not match.", bid->name); } else { - yywarning("Type of identifier %S is not strictly compatible.", - bid->name); - yytype_error(NULL, ID_FROM_INT(a,i)->type, bid->type, YYTE_IS_WARNING); + yytype_report(REPORT_WARNING, + NULL, 0, bid->type, + NULL, 0, ID_FROM_INT(a, i)->type, + 0, "Type of identifier %S is not strictly compatible.", + bid->name); } continue; } } + free_string(b_file); + free_string(a_file); END_CYCLIC(); } diff --git a/src/program.h b/src/program.h index 66c8e79784861b7bfcbf105973682251fc19dfea..bc956412b1025349c23a77253456760bcb7316ad 100644 --- a/src/program.h +++ b/src/program.h @@ -2,7 +2,7 @@ || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. -|| $Id: program.h,v 1.247 2008/05/21 21:55:49 grubba Exp $ +|| $Id: program.h,v 1.248 2008/05/24 15:14:12 grubba Exp $ */ #ifndef PROGRAM_H @@ -53,6 +53,10 @@ PMOD_EXPORT extern struct program_state * Pike_compiler; extern struct pike_string *this_program_string; +/* Common compiler subsystems */ +extern struct pike_string *parser_system_string; +extern struct pike_string *type_check_system_string; + #define LFUN___INIT 0 #define LFUN_CREATE 1 #define LFUN_DESTROY 2 @@ -682,6 +686,12 @@ extern struct object *placeholder_object; #define SEE_STATIC 1 #define SEE_PRIVATE 2 +/* Report levels */ +#define REPORT_NOTICE 0 /* FYI. */ +#define REPORT_WARNING 1 /* Compiler warning. */ +#define REPORT_ERROR 2 /* Compilation error. */ +#define REPORT_FATAL 3 /* Unrecoverable error. */ + #define COMPILER_IN_CATCH 1 @@ -879,8 +889,27 @@ PMOD_EXPORT struct pike_string *get_line(PIKE_OPCODE_T *pc, struct program *prog, INT32 *linep); PMOD_EXPORT struct pike_string *low_get_function_line (struct object *o, int fun, INT32 *linep); -PMOD_EXPORT void va_yyerror(const char *fmt, va_list args); +PMOD_EXPORT void va_yyreport(int severity_level, + struct pike_string *file, INT32 line, + struct pike_string *system, INT32 args, + const char *fmt, va_list vargs); +PMOD_EXPORT void low_yyreport(int severity_level, + struct pike_string *file, INT32 line, + struct pike_string *system, + INT32 args, const char *fmt, ...); +PMOD_EXPORT void yyreport(int severity_level, struct pike_string *system, + INT32 args, const char *fmt, ...); +PMOD_EXPORT void yywarning(char *fmt, ...); PMOD_EXPORT void my_yyerror(const char *fmt,...); +PMOD_EXPORT void yyerror(const char *s); +void yytype_report(int severity_level, + struct pike_string *expect_file, INT32 expect_line, + struct pike_type *expected_t, + struct pike_string *got_file, INT32 got_line, + struct pike_type *got_t, + INT32 args, const char *fmt, ...); +void yytype_error(const char *msg, struct pike_type *expected_t, + struct pike_type *got_t, unsigned int flags); struct pike_string *format_exception_for_error_msg (struct svalue *thrown); void handle_compile_exception (const char *yyerror_fmt, ...); struct supporter_marker; @@ -934,15 +963,13 @@ PMOD_EXPORT struct program *program_from_function(const struct svalue *f); PMOD_EXPORT struct program *program_from_svalue(const struct svalue *s); struct find_child_cache_s; int find_child(struct program *parent, struct program *child); -void va_yyreport(int severity_level, const char *system, - const char *fmt, va_list args); -void yyreport(int severity_level, const char *system, const char *fmt, ...); -void yywarning(char *fmt, ...); struct implements_cache_s; PMOD_EXPORT int implements(struct program *a, struct program *b); PMOD_EXPORT int is_compatible(struct program *a, struct program *b); -void yyexplain_not_compatible(struct program *a, struct program *b, int flags); -void yyexplain_not_implements(struct program *a, struct program *b, int flags); +void yyexplain_not_compatible(int severity_level, + struct program *a, struct program *b); +void yyexplain_not_implements(int severity_level, + struct program *a, struct program *b); PMOD_EXPORT void *parent_storage(int depth); PMOD_EXPORT void change_compiler_compatibility(int major, int minor); void make_program_executable(struct program *p); diff --git a/src/sscanf.c b/src/sscanf.c index b35d1c673543adaedf48832b06a312fbad7cac5b..6acb7d0cda4ee3c938f0af7e53b83767113f1aad 100644 --- a/src/sscanf.c +++ b/src/sscanf.c @@ -2,7 +2,7 @@ || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. -|| $Id: sscanf.c,v 1.183 2008/05/21 21:59:07 grubba Exp $ +|| $Id: sscanf.c,v 1.184 2008/05/24 15:14:12 grubba Exp $ */ #include "global.h" @@ -17,7 +17,6 @@ #include "bignum.h" #include "pike_float.h" #include "pike_types.h" -#include "pike_compiler.h" #include "sscanf.h" #define sp Pike_sp @@ -1642,15 +1641,6 @@ void f_sscanf_76(INT32 args) static void push_sscanf_argument_types(PCHARP format, ptrdiff_t format_len, int cnt, int flags) { - struct compilation *c = THIS_COMPILATION; - int severity_level = REPORT_ERROR; - - if ((c->major != -1) && - ((c->major < 7) || ((c->major == 7) && (c->minor < 7)))) { - /* Compat mode: Pike 7.6 or earlier. */ - severity_level = REPORT_WARNING; - } - for(; cnt < format_len; cnt++) { int no_assign=0; @@ -1677,8 +1667,8 @@ static void push_sscanf_argument_types(PCHARP format, ptrdiff_t format_len, case '5': case '6': case '7': case '8': case '9': cnt++; if(cnt>=format_len) { - yyreport(severity_level, "type_check", - "Error in sscanf format string."); + yyreport(REPORT_ERROR, type_check_system_string, + 0, "Error in sscanf format string."); break; } continue; @@ -1691,8 +1681,8 @@ static void push_sscanf_argument_types(PCHARP format, ptrdiff_t format_len, { if(e>=format_len) { - yyreport(severity_level, "type_check", - "Missing %%} in format string."); + yyreport(REPORT_ERROR, type_check_system_string, + 0, "Missing %%} in format string."); break; } if(INDEX_PCHARP(format, e)=='%') @@ -1741,8 +1731,8 @@ static void push_sscanf_argument_types(PCHARP format, ptrdiff_t format_len, int ch; cnt++; if (cnt >= format_len) { - yyreport(severity_level, "type_check", - "Error in sscanf format string."); + yyreport(REPORT_ERROR, type_check_system_string, + 0, "Error in sscanf format string."); break; } if((INDEX_PCHARP(format, cnt)=='^') && @@ -1753,8 +1743,8 @@ static void push_sscanf_argument_types(PCHARP format, ptrdiff_t format_len, { cnt++; if(cnt >= format_len) { - yyreport(severity_level, "type_check", - "Error in sscanf format string."); + yyreport(REPORT_ERROR, type_check_system_string, + 0, "Error in sscanf format string."); break; } } @@ -1763,8 +1753,8 @@ static void push_sscanf_argument_types(PCHARP format, ptrdiff_t format_len, { cnt++; if(cnt >= format_len) { - yyreport(severity_level, "type_check", - "Error in sscanf format string."); + yyreport(REPORT_ERROR, type_check_system_string, + 0, "Error in sscanf format string."); break; } ch = INDEX_PCHARP(format, cnt); @@ -1776,8 +1766,8 @@ static void push_sscanf_argument_types(PCHARP format, ptrdiff_t format_len, { cnt++; if(cnt >= format_len) { - yyreport(severity_level, "type_check", - "Error in sscanf format string."); + yyreport(REPORT_ERROR, type_check_system_string, + 0, "Error in sscanf format string."); break; } @@ -1788,8 +1778,8 @@ static void push_sscanf_argument_types(PCHARP format, ptrdiff_t format_len, } cnt++; if(cnt>=format_len) { - yyreport(severity_level, "type_check", - "Error in sscanf format string."); + yyreport(REPORT_ERROR, type_check_system_string, + 0, "Error in sscanf format string."); break; } ch = INDEX_PCHARP(format, cnt); @@ -1816,8 +1806,8 @@ static void push_sscanf_argument_types(PCHARP format, ptrdiff_t format_len, break; default: - yyreport(severity_level, "type_check", - "Unknown sscanf token %%%c(0x%02x) at offset %d.", + yyreport(REPORT_ERROR, type_check_system_string, + 0, "Unknown sscanf token %%%c(0x%02x) at offset %d.", INDEX_PCHARP(format, cnt), INDEX_PCHARP(format, cnt), cnt-1); break; @@ -1838,14 +1828,6 @@ void f___handle_sscanf_format(INT32 args) int flags = 0; int found = 0; int fmt_count; - struct compilation *c = THIS_COMPILATION; - int severity_level = REPORT_ERROR; - - if ((c->major != -1) && - ((c->major < 7) || ((c->major == 7) && (c->minor < 7)))) { - /* Compat mode: Pike 7.6 or earlier. */ - severity_level = REPORT_WARNING; - } #if 0 fprintf(stderr, "__handle_sprintf_format()\n"); @@ -1925,11 +1907,6 @@ void f___handle_sscanf_format(INT32 args) res = pop_unfinished_type(); pop_n_elems(args); push_type_value(res); - if (severity_level <= REPORT_WARNING) { - /* Disable further checks in compat mode. */ - pop_stack(); - push_undefined(); - } return; } else { if (!(fmt_count = pop_stack_mark())) { @@ -1969,11 +1946,6 @@ void f___handle_sscanf_format(INT32 args) res = pop_unfinished_type(); pop_n_elems(args); push_type_value(res); - if (severity_level <= REPORT_WARNING) { - /* Disable further checks in compat mode. */ - pop_stack(); - push_undefined(); - } return; } else if (tmp) { /* Check if it's in the return type. */ @@ -2023,11 +1995,6 @@ void f___handle_sscanf_format(INT32 args) res = pop_unfinished_type(); pop_n_elems(args); push_type_value(res); - if (severity_level <= REPORT_WARNING) { - /* Disable further checks in compat mode. */ - pop_stack(); - push_undefined(); - } return; } }