void TraceOpt_update_from_env(TraceOpt_ptr self, const NuSMVEnv_ptr env) { const OptsHandler_ptr opts = OPTS_HANDLER(NuSMVEnv_get_value(env, ENV_OPTS_HANDLER)); const ErrorMgr_ptr errmgr = ERROR_MGR(NuSMVEnv_get_value(env, ENV_ERROR_MANAGER)); StreamMgr_ptr streams = STREAM_MGR(NuSMVEnv_get_value(env, ENV_STREAM_MANAGER)); TRACE_OPT_CHECK_INSTANCE(self); /* We don't own the FILE*, so we need to reset it to avoid OStream_set_stream to close or flush it! */ (void)OStream_reset_stream(self->output_stream); OStream_set_stream(self->output_stream, StreamMgr_get_output_stream(streams)); self->show_defines = opt_show_defines_in_traces(opts); self->show_defines_with_next = opt_backward_comp(opts) ? false : opt_show_defines_with_next(opts); self->hiding_prefix = (char*)opt_traces_hiding_prefix(opts); #if NUSMV_HAVE_REGEX_H { const char* pattern = opt_traces_regexp(opts); /* free previous regexp contents if any */ if ((regex_t *)(NULL) != self->regexp) { regfree(self->regexp); FREE(self->regexp); self->regexp = (regex_t*)(NULL); } /* replace regexp if any has been defined */ if (NIL(char) != pattern) { self->regexp = ALLOC(regex_t, 1); if (0 != regcomp(self->regexp, pattern, REG_EXTENDED|REG_NOSUB)) { ErrorMgr_internal_error(errmgr, "%s:%d:%s: processing regular expression: %s", __FILE__, __LINE__, __func__, pattern); } } } #endif }
/**Function******************************************************************** Synopsis [The type core violation handler.] Description [The violation handler is implemented as a virtual method, which is invoked by the checker when an expression being checked violates the type system. See the violation handler TypeCheckingViolationHandler_ptr for more explanations. The below function is the default violation handler, and a user can potentially define its own violation handler, by deriving a new class from this class and by overriding this virtual method. This violation handler outputs an error and warning message to nusmv_stderr. A warning is output if the detected violation is TC_VIOLATION_TYPE_BACK_COMP and the system variable "type_checking_backward_compatibility" is true. Also the TC_VIOLATION_TYPE_WARNING violation outputs a warning. Only in this case the false value is returned, indicating that this is NOT an error. Otherwise the true value is returned, indicating that this is an error. Also, if the system variable "type_check_warning_on" is false, warning messages are not output. NB: if the expression is checked in some context (context is not null) then before providing the expression to this function the expression should be wrapped into context, i.e. with find_node(CONEXT, context, expr)] SideEffects [] SeeAlso [TypeSystemViolation] ******************************************************************************/ static boolean checker_psl_viol_handler(CheckerBase_ptr self, TypeSystemViolation violation, node_ptr expression) { /* In the output message, the information about the expression location are output. So, make sure that the input file name and line number are correctly set! */ boolean isError = true; /* is this error or warning */ /* get rid of the context the expression may be wrapped in */ PslNode_ptr context = PSL_NULL; PslNode_ptr expr = PslNode_convert_from_node_ptr(expression); if (node_get_type(expression) == CONTEXT) { context = PslNode_convert_from_node_ptr(car(expression)); expr = PslNode_convert_from_node_ptr(cdr(expression)); } /* checks the given violation */ nusmv_assert(TypeSystemViolation_is_valid(violation)); /* only violation TC_VIOLATION_TYPE_BACK_COMP and the variable type_checking_backward_compatibility being true, may make a warning from an error. TC_VIOLATION_TYPE_WARNING always forces a warning */ if ( TC_VIOLATION_TYPE_WARNING == violation || ( TC_VIOLATION_TYPE_BACK_COMP == violation && opt_backward_comp(OptsHandler_get_instance()))) { isError = false; } if (!isError && !opt_type_checking_warning_on(OptsHandler_get_instance())) { /* this is a warning and warning messages are not allowed. So, do nothing, just return false (this is not an error) */ return false; } _PRINT_ERROR_MSG(expr, isError); switch (violation) { case TC_VIOLATION_AMBIGUOUS_IDENTIFIER: fprintf(nusmv_stderr, "identifier '"); print_node(nusmv_stderr, PslNode_convert_to_node_ptr(expr)); fprintf(nusmv_stderr, "' is ambiguous\n"); break; case TC_VIOLATION_UNCONSTANT_EXPRESSION: fprintf(nusmv_stderr, "Expected constant expression in '"); print_node(nusmv_stderr, PslNode_convert_to_node_ptr(expr)); fprintf(nusmv_stderr, "'\n"); break; case TC_VIOLATION_TYPE_MANDATORY: case TC_VIOLATION_TYPE_BACK_COMP: case TC_VIOLATION_TYPE_WARNING: if (isError) fprintf(nusmv_stderr, "illegal "); else fprintf(nusmv_stderr, "potentially incorrect "); switch (psl_node_get_op(expr)) { case PSL_SERE: case PSL_SERECOMPOUND: fprintf(nusmv_stderr, "sere type of {"); print_node(stderr, PslNode_convert_to_node_ptr(psl_node_get_left(expr))); fprintf(nusmv_stderr, "} : "); checker_base_print_type(self, nusmv_stderr, PslNode_convert_to_node_ptr(psl_node_get_left(expr)), PslNode_convert_to_node_ptr(context)); break; case PSL_SERECONCAT: fprintf(nusmv_stderr, "operand types of sere concatenation: "); checker_base_print_type(self, nusmv_stderr, PslNode_convert_to_node_ptr(psl_node_get_left(expr)), PslNode_convert_to_node_ptr(context)); fprintf(nusmv_stderr, " "); print_operator(nusmv_stderr, expr); fprintf(nusmv_stderr, " "); checker_base_print_type(self, nusmv_stderr, PslNode_convert_to_node_ptr(psl_node_get_right(expr)), PslNode_convert_to_node_ptr(context)); break; case PSL_SEREFUSION: fprintf(nusmv_stderr, "operand types of sere fusion: "); checker_base_print_type(self, nusmv_stderr, PslNode_convert_to_node_ptr(psl_node_get_left(expr)), PslNode_convert_to_node_ptr(context)); fprintf(nusmv_stderr, " "); print_operator(nusmv_stderr, expr); fprintf(nusmv_stderr, " "); checker_base_print_type(self, nusmv_stderr, PslNode_convert_to_node_ptr(psl_node_get_right(expr)), PslNode_convert_to_node_ptr(context)); break; case PSL_SEREREPEATED: { PslNode_ptr sere = psl_node_sere_repeated_get_expr(expr); PslNode_ptr count = psl_node_sere_repeated_get_count(expr); fprintf(nusmv_stderr, "operand types of sere repeated: "); if (sere != PSL_NULL) { checker_base_print_type(self, nusmv_stderr, PslNode_convert_to_node_ptr(sere), PslNode_convert_to_node_ptr(context)); } print_operator(nusmv_stderr, psl_node_get_left(expr)); fprintf(nusmv_stderr, " "); if (count != PSL_NULL) { checker_base_print_type(self, nusmv_stderr, PslNode_convert_to_node_ptr(count), PslNode_convert_to_node_ptr(context)); } fprintf(nusmv_stderr, " ]"); break; } case PSL_REPLPROP: { PslNode_ptr prop = psl_node_repl_prop_get_property(expr); fprintf(nusmv_stderr, "operand type of "); print_operator(nusmv_stderr, expr); fprintf(nusmv_stderr, " property: "); checker_base_print_type(self, nusmv_stderr, PslNode_convert_to_node_ptr(prop), PslNode_convert_to_node_ptr(context)); break; } /* suffix implication */ case PSL_PIPEMINUSGT: case PSL_PIPEEQGT: { PslNode_ptr pre = psl_node_suffix_implication_get_premise(expr); PslNode_ptr con = psl_node_suffix_implication_get_consequence(expr); fprintf(nusmv_stderr, "operand types of suffix implication: "); checker_base_print_type(self, nusmv_stderr, PslNode_convert_to_node_ptr(pre), PslNode_convert_to_node_ptr(context)); fprintf(nusmv_stderr, " "); print_operator(nusmv_stderr, expr); fprintf(nusmv_stderr, " "); checker_base_print_type(self, nusmv_stderr, PslNode_convert_to_node_ptr(con), PslNode_convert_to_node_ptr(context)); break; } /* unary operators: */ case PSL_ALWAYS: case PSL_NEVER: case PSL_EVENTUALLYBANG: fprintf(nusmv_stderr, "operand types of \""); print_operator(nusmv_stderr, expr); fprintf(nusmv_stderr, "\" : "); checker_base_print_type(self, nusmv_stderr, PslNode_convert_to_node_ptr(psl_node_get_left(expr)), PslNode_convert_to_node_ptr(context)); break; /* within operators */ case PSL_WITHINBANG: case PSL_WITHIN: case PSL_WITHINBANG_: case PSL_WITHIN_: { PslNode_ptr n1 = psl_node_get_left(psl_node_get_left(expr)); PslNode_ptr n2 = psl_node_get_right(psl_node_get_left(expr)); PslNode_ptr n3 = psl_node_get_right(expr); fprintf(nusmv_stderr, "operand types of \""); print_operator(nusmv_stderr, expr); fprintf(nusmv_stderr, "\" : ("); checker_base_print_type(self, nusmv_stderr, PslNode_convert_to_node_ptr(n1), PslNode_convert_to_node_ptr(context)); fprintf(nusmv_stderr, ", "); checker_base_print_type(self, nusmv_stderr, PslNode_convert_to_node_ptr(n2), PslNode_convert_to_node_ptr(context)); fprintf(nusmv_stderr, ") "); checker_base_print_type(self, nusmv_stderr, PslNode_convert_to_node_ptr(n3), PslNode_convert_to_node_ptr(context)); break; } /* next operators */ case PSL_NEXT_EVENT_ABANG: case PSL_NEXT_EVENT_A: case PSL_NEXT_EVENT_EBANG: case PSL_NEXT_EVENT_E: case PSL_NEXT_EVENTBANG: case PSL_NEXT_EVENT: case PSL_NEXT_ABANG: case PSL_NEXT_EBANG: case PSL_NEXT_A: case PSL_NEXT_E: case PSL_NEXTBANG: case PSL_NEXT: case PSL_X: case PSL_XBANG: { PslNode_ptr n1 = psl_node_extended_next_get_expr(expr); PslNode_ptr n2 = psl_node_extended_next_get_when(expr); PslNode_ptr n3 = psl_node_extended_next_get_condition(expr); fprintf(nusmv_stderr, "operand types of \""); print_operator(nusmv_stderr, expr); fprintf(nusmv_stderr, "\" : "); if (n3 != PSL_NULL) { fprintf(nusmv_stderr, " ("); checker_base_print_type(self, nusmv_stderr, PslNode_convert_to_node_ptr(n3), PslNode_convert_to_node_ptr(context)); fprintf(nusmv_stderr, ")"); } if (n2 != PSL_NULL) { fprintf(nusmv_stderr, " ["); checker_base_print_type(self, nusmv_stderr, PslNode_convert_to_node_ptr(n2), PslNode_convert_to_node_ptr(context)); fprintf(nusmv_stderr, "]"); } nusmv_assert(n1 != PSL_NULL); /* n1 must occur here */ fprintf(nusmv_stderr, " ("); checker_base_print_type(self, nusmv_stderr, PslNode_convert_to_node_ptr(n1), PslNode_convert_to_node_ptr(context)); fprintf(nusmv_stderr, ")"); break; } /* Binary operators */ case PSL_BEFOREBANG: case PSL_BEFORE: case PSL_BEFOREBANG_: case PSL_BEFORE_: case PSL_UNTILBANG: case PSL_UNTIL: case PSL_UNTILBANG_: case PSL_UNTIL_: case PSL_ABORT: case PSL_W: case PSL_OR: case PSL_CARET: case PSL_TILDE: case PSL_EQEQ: case PSL_PIPEPIPE: case PSL_AMPERSANDAMPERSAND: case PSL_WHILENOTBANG: case PSL_WHILENOT: case PSL_WHILENOTBANG_: case PSL_WHILENOT_: fprintf(nusmv_stderr, "operand types of \""); print_operator(nusmv_stderr, expr); fprintf(nusmv_stderr,"\" : "); checker_base_print_type(self, nusmv_stderr, PslNode_convert_to_node_ptr(psl_node_get_left(expr)), PslNode_convert_to_node_ptr(context)); fprintf(nusmv_stderr," and "); checker_base_print_type(self, nusmv_stderr, PslNode_convert_to_node_ptr(psl_node_get_right(expr)), PslNode_convert_to_node_ptr(context)); break; case PSL_ITE: fprintf(nusmv_stderr, "operand types of \""); print_operator(nusmv_stderr, expr); fprintf(nusmv_stderr,"\" : "); checker_base_print_type(self, nusmv_stderr, PslNode_convert_to_node_ptr(psl_node_get_ite_cond(expr)), PslNode_convert_to_node_ptr(context)); fprintf(nusmv_stderr," ? "); checker_base_print_type(self, nusmv_stderr, PslNode_convert_to_node_ptr(psl_node_get_ite_then(expr)), PslNode_convert_to_node_ptr(context)); fprintf(nusmv_stderr," : "); checker_base_print_type(self, nusmv_stderr, PslNode_convert_to_node_ptr(psl_node_get_ite_else(expr)), PslNode_convert_to_node_ptr(context)); break; default: /* unknown kind of an expression */ error_unreachable_code(); } /* switch (node_get_type(expr)) */ fprintf(nusmv_stderr,"\n"); break; default: error_unreachable_code(); /* unknown kind of error */ } /* switch (errorKind) */ return isError; }