Esempio n. 1
0
 def error_check_logical_operators(self, sorted_analysis_unit_dict):
     ''' ERR CHECK UNITS DURING LOGICAL OPERATIONS
         input: sorted analysis unit dictionary of functions
         returns: none
         side_effects: might add UnitError objects to self.all_errors list
         '''
     for function_dict in sorted_analysis_unit_dict.values():
         tw = TreeWalker(None)
         for root_token in function_dict['root_tokens']:
             tw.generic_recurse_and_apply_function(
                 root_token, self.error_check_logical_recursive)
Esempio n. 2
0
 def error_check_comparisons(self, sorted_analysis_unit_dict):
     ''' ERR CHECK COMPARISION OF UNITS OVER LOGICAL OPERATORS  
         input: sorted analysis unit dictionary of functions
         returns: none
         side_effects: might add UnitError objects to self.all_errors list
         '''
     for function_dict in sorted_analysis_unit_dict.values():
         tw = TreeWalker(None)
         for root_token in function_dict['root_tokens']:
             tw.generic_recurse_and_apply_function(
                 root_token, self.error_check_comparison_recursive)
Esempio n. 3
0
 def error_check_logical_operators(self, sorted_analysis_unit_dict):
     ''' ERR CHECK UNITS DURING LOGICAL OPERATIONS
         input: cppcheck configuration unit from dump
         returns: none
         side_effects:  might add UnitError objects to self.all_errors list
         '''
     for function_dict in sorted_analysis_unit_dict.values():
         tw = TreeWalker(
             function_dict
         )  # ARGUMENT 'FUNCTION DICTIONARY' IS USED BY SYMBOL TABLE
         for root_token in function_dict['root_tokens']:
             tw.generic_recurse_and_apply_function(
                 root_token, self.error_check_logical_recursive_target)
Esempio n. 4
0
 def error_check_addition_of_incompatible_units(self,
                                                sorted_analysis_unit_dict):
     ''' ERROR CHECK ADDITION OF INCOMPATIBLE UNITS
         input: sorted analysis unit dictionary of functions
         returns: none
         side_effects: might add UnitError objects to self.all_errors list
         '''
     for function_dict in sorted_analysis_unit_dict.values():
         tw = TreeWalker(None)
         for root_token in function_dict['root_tokens']:
             self.have_found_addition_error_on_this_line = False
             tw.generic_recurse_and_apply_function(
                 root_token,
                 self.error_check_addition_of_incompatible_units_recursive)
Esempio n. 5
0
def _get_walker(config, storage, list_format):
    if list_format == Config.LIST_FORMAT_TREE:
        return TreeWalker(config, storage)
    elif list_format == Config.LIST_FORMAT_CSV:
        return CsvWalker(config, storage)
    else:
        raise ValueError(
            'Unrecognised value for list-format: {}'.format(list_format))
Esempio n. 6
0
 def error_check_addition_of_incompatible_units(self,
                                                sorted_analysis_unit_dict):
     ''' ERROR CHECK ADDITIONAL OF INCOMPATIBLE UNITS
         input: cppcheck configuration unit from dump
         returns: none
         side_effects:  might add UnitError objects to self.all_errors list
         '''
     if self.debug:
         print 'call to error_check_addition_of_incompatible_units'
     for function_dict in sorted_analysis_unit_dict.values():
         tw = TreeWalker(
             function_dict
         )  # ARGUMENT 'FUNCTION DICTIONARY' IS USED BY SYMBOL TABLE
         self.have_found_addition_error_on_this_line = False
         for root_token in function_dict['root_tokens']:
             # tw.is_assignment_statement = False
             # tw.generic_recurse_and_apply_function(root_token, tw.find_assignment_tokens_recursive_target)
             # if not tw.is_assignment_statement:
             tw.generic_recurse_and_apply_function(
                 root_token, self.
                 error_check_addition_of_incompatible_units_recursive_target
             )
Esempio n. 7
0
    def print_unit_errors(self,
                          errors_file,
                          show_high_confidence=True,
                          show_low_confidence=False):
        error_type_text = [
            'VARIABLE_MULTIPLE_UNITS',
            'COMPARISON_INCOMPATIBLE_UNITS',
            'VARIABLE_BECAME_UNITLESS',
            'FUNCTION_CALLED_WITH_DIFFERENT_UNIT_ARGUMENTS',
            'VARIABLE_WITH_UNUSUAL_UNITS',
            'ADDITION_OF_INCOMPATIBLE_UNITS',
            'LOGICAL_OPERATOR_USED_ON_UNITS',
            'UNIT_SMELL',
        ]
        tw = TreeWalker(None)

        with open(errors_file, 'w') as f:
            for e in self.all_errors:
                is_high_confidence = not e.is_warning
                is_low_confidence = e.is_warning

                if is_high_confidence and not show_high_confidence:
                    continue
                if is_low_confidence and not show_low_confidence:
                    continue

                linenr = e.linenr
                etype = error_type_text[e.ERROR_TYPE]
                name = e.var_name
                f.write("%s, %s, %s\n" % (linenr, name, etype))

                if e.ERROR_TYPE == UnitErrorTypes.FUNCTION_CALLED_WITH_DIFFERENT_UNIT_ARGUMENTS:
                    tw.generic_recurse_and_apply_function(
                        e.token_left, self.collect_var_units_for_check)
                    tw.generic_recurse_and_apply_function(
                        e.token_right, self.collect_var_units_for_check)
                else:
                    tw.generic_recurse_and_apply_function(
                        e.token, self.collect_var_units_for_check)
Esempio n. 8
0
    def recheck_unit_errors(self, correction_file, dump_file, source_file):
        with open(correction_file) as f:
            for var_result in (line.rstrip('\n') for line in f):
                var_name, var_unit = var_result.split(',', 1)
                var_name, var_unit = var_name.strip(), var_unit.strip()
                var_unit = eval(var_unit)
                con.phys_corrections[var_name] = var_unit

        #print "phys_corrections: %s" % con.phys_corrections

        a_cppcheck_configuration = self.get_cppcheck_config_data_structure(
            dump_file)
        errors, varlist = self.load_state(a_cppcheck_configuration)

        err_checker = ErrorChecker(dump_file, source_file)
        show_high_confidence = True
        show_low_confidence = False

        for e in errors:
            is_high_confidence = not e.is_warning
            is_low_confidence = e.is_warning

            if is_high_confidence and not show_high_confidence:
                continue
            if is_low_confidence and not show_low_confidence:
                continue

            if e.ERROR_TYPE == UnitErrorTypes.VARIABLE_MULTIPLE_UNITS:
                tw = TreeWalker(None)
                self.apply_and_propagate_units(tw, e.token)

                # TRACK VARIABLE WITH MULTIPLE UNITS
                if len(e.token.astOperand2.units) > 1:
                    e.units_when_multiple_happened = e.token.astOperand2.units
                    err_checker.all_errors.append(e)

                if e.token_left.isKnown:
                    # TRACK VARIABLE WITH MULTIPLE UNITS
                    if (len(e.token.astOperand2.units) == 1) and (
                            e.token_left.units != e.token.astOperand2.units):
                        units = []
                        units.extend(e.token_left.units)
                        units.extend(e.token.astOperand2.units)
                        e.units_when_multiple_happened = units
                        err_checker.all_errors.append(e)

            elif e.ERROR_TYPE == UnitErrorTypes.FUNCTION_CALLED_WITH_DIFFERENT_UNIT_ARGUMENTS:
                tw = TreeWalker(None)
                self.apply_and_propagate_units(tw, e.token_left)
                self.apply_and_propagate_units(tw, e.token_right)

                # UPDATE UNITS AT BOTH CALL POINTS
                e.units_at_first_assignment = e.token_left.units
                e.units_when_multiple_happened = e.token_right.units

                # CHECK UNITS OF FIRST CALL POINT AGAINST THE OTHER CALL POINT
                if e.units_when_multiple_happened != e.units_at_first_assignment:
                    err_checker.all_errors.append(e)

            elif e.ERROR_TYPE == UnitErrorTypes.ADDITION_OF_INCOMPATIBLE_UNITS:
                tw = TreeWalker(None)
                self.apply_and_propagate_units(tw, e.token)
                err_checker.have_found_addition_error_on_this_line = False
                tw.generic_recurse_and_apply_function(
                    e.token, err_checker.
                    error_check_addition_of_incompatible_units_recursive)

            elif e.ERROR_TYPE == UnitErrorTypes.COMPARISON_INCOMPATIBLE_UNITS:
                tw = TreeWalker(None)
                self.apply_and_propagate_units(tw, e.token)
                tw.generic_recurse_and_apply_function(
                    e.token, err_checker.error_check_comparison_recursive)

            else:
                err_checker.all_errors.append(e)

        print "Error_Rechecker:"
        err_checker.pretty_print()
        err_checker.print_unit_errors('errors_2.txt')
        self.print_var_units_to_check(err_checker, varlist,
                                      'variable_units_to_check_2.txt')
Esempio n. 9
0
    def propagate_units(self, function_dict):
        tw = TreeWalker(self.type_miner)  

        # ASSUME THE TOKENS COME BACK AS A SORTED LIST
        break_point = 1000
        i=0

        for root_token in function_dict['root_tokens']:
            #print root_token.str, root_token.linenr
            tw.is_unit_propagation_based_on_constants = False
            tw.is_unit_propagation_based_on_unknown_variable = False
            tw.found_arg_var = False
            tw.found_non_arg_var = False

            # RESET THE TREE WALKER'S LINE NUMBERS
            tw.reset_min_max_line_numbers()
            # FIND THE MIN AND MAX LINE NUMBERS IN THIS AST : USED TO PROTECT LOOP FROM MULTI-LINE STATEMENTS
            tw.generic_recurse_and_apply_function(root_token, tw.find_min_max_line_numbers)
            # SCAN VARIABLES
            tw.generic_recurse_and_apply_function(root_token, tw.scan_variables)

            # APPLY ROS UNITS TO VARIABLES
            tw.generic_recurse_and_apply_function(root_token, tw.apply_ROS_units)
            # APPLY UNITS TO KNOWN SYMBOLS
            tw.generic_recurse_and_apply_function(root_token, tw.apply_known_symbols_units)
            # APPLY UNITS FROM KNOWN FUNCTION - getX, getY, getZ  
            tw.generic_recurse_and_apply_function(root_token, tw.apply_units_getXYZ)
            # APPLY UNITS TO CONVERSION FACTORS
            tw.generic_recurse_and_apply_function(root_token, tw.apply_conversion_factor_units)
            # APPLY FUNCTION RETURN UNITS
            tw.generic_recurse_and_apply_function(root_token, tw.apply_function_return_units)
            # APPLY UNITS FROM PREVIOUS ROUND
            tw.generic_recurse_and_apply_function(root_token, tw.apply_previous_round_units)
            # APPLY DIMENSIONLESS UNITS
            tw.generic_recurse_and_apply_function(root_token, tw.apply_dimensionless_units)


            if (not tw.was_some_unit_changed):
                tw.generic_recurse_and_apply_function(root_token, tw.propagate_units_across_return)

            
            # CONTINUE TO ATTEMPT CHANGES UNTIL CHANGES CEASE
            while tw.was_some_unit_changed:  
                if i>break_point:
                    s = "BREAKING WHILE LOOP AT %d" % break_point
                    raise ValueError(s)
                    return
                i+=1
                tw.was_some_unit_changed = False
                # LOOK FOR EARLY ABANDONMENT OF THIS AST
                if not tw.found_units_in_this_tree and self.should_abandon_early:
                    break
                ### PROPAGATE UNITS
                tw.generic_recurse_and_apply_function(root_token, tw.propagate_units_across_dot_connectors)
                tw.generic_recurse_and_apply_function(root_token, tw.propagate_units_across_double_colon)                
                tw.generic_recurse_and_apply_function(root_token, tw.propagate_units_across_square_brackets)
                tw.generic_recurse_and_apply_function(root_token, tw.propagate_units_across_assignment)
                tw.generic_recurse_and_apply_function(root_token, tw.propagate_units_math_abs_fabs_floor_ceil)
                tw.generic_recurse_and_apply_function(root_token, tw.propagate_units_math_min_max)
                tw.generic_recurse_and_apply_function(root_token, tw.propagate_units_math_fmod_fmodf_fmodl)
                tw.generic_recurse_and_apply_function(root_token, tw.propagate_units_sqrt)
                # tw.generic_recurse_and_apply_function(root_token, tw.propagate_units_getXYZ)
                tw.generic_recurse_and_apply_function(root_token, tw.propagate_units_ternary)
                tw.generic_recurse_and_apply_function(root_token, tw.propagate_units_pow)
                tw.generic_recurse_and_apply_function(root_token, tw.propagate_units_inverse_trig)
                tw.generic_recurse_and_apply_function(root_token, tw.propagate_units_across_operators)
                tw.generic_recurse_and_apply_function(root_token, tw.propagate_units_across_return)
                tw.generic_recurse_and_apply_function(root_token, tw.collect_function_param_units_and_decorate_function)
                tw.generic_recurse_and_apply_function(root_token, tw.propagate_units_across_parenthesis)
            # END -- WHILE LOOP

            #RETURN STATEMENT WITH UNITS - STORE UNITS
            if root_token.str == 'return' and root_token.units:
                if function_dict['scopeObject'].function:
                    function_return_units = function_dict['scopeObject'].function.return_units
                    for u in root_token.units:
                        if u not in function_return_units:
                            function_return_units.append(u)

            #ASSIGNMENT STATEMENT WITH UNITS - COLLECT MULTIPLE ASSIGNMENT INCONSISTENCY
            if root_token.isAssignmentOp:
                tw.collect_lhs_unit_constraint(root_token)
Esempio n. 10
0
    def collect_constraints(self, function_dict):
        tw = TreeWalker(self.type_miner, self.vnh)
        tw.current_file = self.current_file_under_analysis
        tw.source_file_lines = self.source_file_lines
        tw.source_file = self.source_file

        # ASSUME THE TOKENS COME BACK AS A SORTED LIST
        break_point = 1000
        i = 0
        found_units = False

        for root_token in function_dict['root_tokens']:
            #print root_token.str, root_token.linenr
            tw.is_unit_propagation_based_on_constants = False
            tw.is_unit_propagation_based_on_unknown_variable = False
            tw.current_child_vars = []
            tw.found_arg_var = False
            tw.found_non_arg_var = False

            # RESET THE TREE WALKER'S LINE NUMBERS
            tw.reset_min_max_line_numbers()
            # FIND THE MIN AND MAX LINE NUMBERS IN THIS AST : USED TO PROTECT LOOP FROM MULTI-LINE STATEMENTS
            tw.generic_recurse_and_apply_function(root_token,
                                                  tw.find_min_max_line_numbers)
            # SCAN VARIABLES
            tw.generic_recurse_and_apply_function(root_token,
                                                  tw.scan_variables)

            # APPLY ROS UNITS TO VARIABLES
            tw.generic_recurse_and_apply_function(root_token,
                                                  tw.apply_ROS_units)
            # APPLY UNITS TO KNOWN SYMBOLS
            tw.generic_recurse_and_apply_function(root_token,
                                                  tw.apply_known_symbols_units)
            # APPLY UNITS FROM KNOWN FUNCTION - getX, getY, getZ
            tw.generic_recurse_and_apply_function(root_token,
                                                  tw.apply_units_getXYZ)
            # APPLY UNITS TO CONVERSION FACTORS
            tw.generic_recurse_and_apply_function(
                root_token, tw.apply_conversion_factor_units)
            # APPLY FUNCTION RETURN UNITS
            tw.generic_recurse_and_apply_function(
                root_token, tw.apply_function_return_units)
            # APPLY DIMENSIONLESS UNITS
            tw.generic_recurse_and_apply_function(root_token,
                                                  tw.apply_dimensionless_units)

            if (tw.found_units_in_this_tree):
                found_units = True

            if (not tw.was_some_unit_changed):
                tw.generic_recurse_and_apply_function(
                    root_token, tw.propagate_units_across_return)

            # CONTINUE TO ATTEMPT CHANGES UNTIL CHANGES CEASE
            while tw.was_some_unit_changed:
                if i > break_point:
                    s = "BREAKING WHILE LOOP AT %d" % break_point
                    raise ValueError(s)
                    return
                i += 1
                tw.was_some_unit_changed = False
                # LOOK FOR EARLY ABANDONMENT OF THIS AST
                if not tw.found_units_in_this_tree and self.should_abandon_early:
                    break
                ### PROPAGATE UNITS
                tw.generic_recurse_and_apply_function(
                    root_token, tw.propagate_units_across_dot_connectors)
                tw.generic_recurse_and_apply_function(
                    root_token, tw.propagate_units_across_double_colon)
                tw.generic_recurse_and_apply_function(
                    root_token, tw.propagate_units_across_square_brackets)
                tw.generic_recurse_and_apply_function(
                    root_token, tw.propagate_units_across_assignment)
                tw.generic_recurse_and_apply_function(
                    root_token, tw.propagate_units_math_abs_fabs_floor_ceil)
                tw.generic_recurse_and_apply_function(
                    root_token, tw.propagate_units_math_min_max)
                tw.generic_recurse_and_apply_function(
                    root_token, tw.propagate_units_math_fmod_fmodf_fmodl)
                tw.generic_recurse_and_apply_function(root_token,
                                                      tw.propagate_units_sqrt)
                # tw.generic_recurse_and_apply_function(root_token, tw.propagate_units_getXYZ)
                tw.generic_recurse_and_apply_function(
                    root_token, tw.propagate_units_ternary)
                tw.generic_recurse_and_apply_function(root_token,
                                                      tw.propagate_units_pow)
                tw.generic_recurse_and_apply_function(
                    root_token, tw.propagate_units_inverse_trig)
                tw.generic_recurse_and_apply_function(
                    root_token, tw.propagate_units_across_operators)
                tw.generic_recurse_and_apply_function(
                    root_token, tw.propagate_units_across_return)
                tw.generic_recurse_and_apply_function(
                    root_token,
                    tw.collect_function_param_units_and_decorate_function)
                tw.generic_recurse_and_apply_function(
                    root_token, tw.propagate_units_across_parenthesis)
            # END -- WHILE LOOP

            #RETURN STATEMENT WITH UNITS - STORE UNITS
            if root_token.str == 'return' and root_token.units:
                if function_dict['scopeObject'].function:
                    function_return_units = function_dict[
                        'scopeObject'].function.return_units
                    for u in root_token.units:
                        if u not in function_return_units:
                            function_return_units.append(u)

            #ASSIGNMENT STATEMENT WITH UNITS - RIGHT TO LEFT PROPAGATION CONSTRAINT
            if root_token.isAssignmentOp:
                tw.collect_lhs_unit_constraint(root_token)

            #tw.generic_recurse_and_apply_function(root_token, tw.collect_implied_non_unit_variables)
            #SAME UNIT CONSTRAINTS
            tw.generic_recurse_and_apply_function(
                root_token, tw.collect_same_unit_constraints)
            tw.generic_recurse_and_apply_function(
                root_token, tw.collect_same_unit_constraints_II)
            tw.generic_recurse_and_apply_function(
                root_token, tw.collect_same_unit_constraints_III)
            #CONVERSION FACTOR CONSTRAINTS
            #tw.generic_recurse_and_apply_function(root_token, tw.collect_conversion_factor_constraints)
            tw.generic_recurse_and_apply_function(
                root_token, tw.collect_angle_unit_constraints)
            #KNOWN SYMBOL CONSTRAINTS
            tw.generic_recurse_and_apply_function(
                root_token, tw.collect_known_symbol_constraints)
            if not self.SHOULD_USE_DEEP_LEARNING_VAR_NAME_HEURISTIC:
                #NAMING CONSTRAINTS
                tw.generic_recurse_and_apply_function(
                    root_token, tw.collect_naming_constraints)
            else:
                #DEEP LEARNING NAMING CONSTRAINTS
                tw.generic_recurse_and_apply_function(
                    root_token, tw.collect_deep_network_naming_constraints)
        # END -- FOR LOOP

        if (not found_units) and function_dict['scopeObject'].function \
                and ((not tw.found_var) or (tw.found_arg_or_local_var)):
            #and function_dict['scopeObject'].function.argument:
            function_dict['scopeObject'].function.maybe_generic_function = True
Esempio n. 11
0
    def check_error_when_top3_units(self, root_token):
        tw = TreeWalker(None)

        # ASSUME THE TOKENS COME BACK AS A SORTED LIST
        break_point = 1000
        i = 0

        tw.is_unit_propagation_based_on_constants = False
        tw.is_unit_propagation_based_on_unknown_variable = False

        # RESET THE TREE WALKER'S LINE NUMBERS
        tw.reset_min_max_line_numbers()
        # FIND THE MIN AND MAX LINE NUMBERS IN THIS AST : USED TO PROTECT LOOP FROM MULTI-LINE STATEMENTS
        tw.generic_recurse_and_apply_function(root_token,
                                              tw.find_min_max_line_numbers)

        # APPLY ROS UNITS TO VARIABLES
        tw.generic_recurse_and_apply_function(root_token, tw.apply_ROS_units)
        # APPLY UNITS TO KNOWN SYMBOLS
        tw.generic_recurse_and_apply_function(root_token,
                                              tw.apply_known_symbols_units)
        # APPLY UNITS FROM KNOWN FUNCTION - getX, getY, getZ
        tw.generic_recurse_and_apply_function(root_token,
                                              tw.apply_units_getXYZ)
        # APPLY UNITS TO CONVERSION FACTORS
        tw.generic_recurse_and_apply_function(root_token,
                                              tw.apply_conversion_factor_units)
        # APPLY FUNCTION RETURN UNITS
        tw.generic_recurse_and_apply_function(root_token,
                                              tw.apply_function_return_units)
        # APPLY UNITS FROM PREVIOUS ROUND
        tw.generic_recurse_and_apply_function(
            root_token, tw.apply_previous_round_top3_units)
        # APPLY DIMENSIONLESS UNITS
        tw.generic_recurse_and_apply_function(root_token,
                                              tw.apply_dimensionless_units)

        if (not tw.was_some_unit_changed):
            tw.generic_recurse_and_apply_function(
                root_token, tw.propagate_units_across_return)

        # CONTINUE TO ATTEMPT CHANGES UNTIL CHANGES CEASE
        while tw.was_some_unit_changed:
            if i > break_point:
                s = "BREAKING WHILE LOOP AT %d" % break_point
                raise ValueError(s)
                return
            i += 1
            tw.was_some_unit_changed = False
            # LOOK FOR EARLY ABANDONMENT OF THIS AST
            if not tw.found_units_in_this_tree:
                break
            ### PROPAGATE UNITS
            tw.generic_recurse_and_apply_function(
                root_token, tw.propagate_units_across_dot_connectors)
            tw.generic_recurse_and_apply_function(
                root_token, tw.propagate_units_across_double_colon)
            tw.generic_recurse_and_apply_function(
                root_token, tw.propagate_units_across_square_brackets)
            tw.generic_recurse_and_apply_function(
                root_token, tw.propagate_units_across_assignment)
            tw.generic_recurse_and_apply_function(
                root_token, tw.propagate_units_math_abs_fabs_floor_ceil)
            tw.perform_intersection = True
            tw.generic_recurse_and_apply_function(
                root_token, tw.propagate_units_math_min_max)
            tw.perform_intersection = False
            tw.perform_intersection = True
            tw.generic_recurse_and_apply_function(
                root_token, tw.propagate_units_math_fmod_fmodf_fmodl)
            tw.perform_intersection = False
            tw.generic_recurse_and_apply_function(root_token,
                                                  tw.propagate_units_sqrt)
            # tw.generic_recurse_and_apply_function(root_token, tw.propagate_units_getXYZ)
            tw.perform_intersection = True
            tw.generic_recurse_and_apply_function(root_token,
                                                  tw.propagate_units_ternary)
            tw.perform_intersection = False
            tw.generic_recurse_and_apply_function(root_token,
                                                  tw.propagate_units_pow)
            tw.generic_recurse_and_apply_function(
                root_token, tw.propagate_units_inverse_trig)
            tw.perform_intersection = True
            tw.generic_recurse_and_apply_function(
                root_token, tw.propagate_units_across_operators)
            tw.perform_intersection = False
            tw.generic_recurse_and_apply_function(
                root_token, tw.propagate_units_across_return)
            tw.generic_recurse_and_apply_function(
                root_token,
                tw.collect_function_param_units_and_decorate_function)
            tw.generic_recurse_and_apply_function(
                root_token, tw.propagate_units_across_parenthesis)
Esempio n. 12
0
    def check_errors_with_low_confidence_when_top3_units(
            self, cppcheck_configuration_unit, sorted_analysis_unit_dict):
        # need to work on another copy of cppcheckdata
        # check after all errors are collected

        con.print_known_unit_variables()

        data = cppcheckdata.parsedump(self.dump_file)
        for c in data.configurations[:1]:
            break

        # copy token and function data from original config
        tokenlist = {}

        for t in cppcheck_configuration_unit.tokenlist:
            tokenlist[t.Id] = (t.isRoot, t.isDimensionless)

        functionlist = {}
        returnexprtokenlist = {}

        for f in cppcheck_configuration_unit.functions:
            functionlist[f.Id] = (
                f.return_units, f.arg_units, f.return_arg_var_nr,
                f.return_expr_root_token,
                f.is_unit_propagation_based_on_constants,
                f.is_unit_propagation_based_on_unknown_variable,
                f.is_unit_propagation_based_on_weak_inference,
                f.maybe_generic_function)

            if f.return_expr_root_token:
                returnexprtokenlist[f.return_expr_root_token.Id] = None

        returntokenlist = {}

        for t in c.tokenlist:
            (isRoot, isDimensionless) = tokenlist[t.Id]

            t.units = []
            t.isKnown = False
            t.is_unit_propagation_based_on_constants = False
            t.is_unit_propagation_based_on_unknown_variable = False
            t.is_unit_propagation_based_on_weak_inference = False
            t.isRoot = isRoot
            t.isDimensionless = isDimensionless

            if t.str == "return":
                returntokenlist[t.Id] = t

            if t.Id in returnexprtokenlist:
                returnexprtokenlist[t.Id] = t

        for f in c.functions:
            (return_units, arg_units, return_arg_var_nr,
             return_expr_root_token, is_unit_propagation_based_on_constants,
             is_unit_propagation_based_on_unknown_variable,
             is_unit_propagation_based_on_weak_inference,
             maybe_generic_function) = functionlist[f.Id]

            if return_expr_root_token:
                return_expr_root_token = returnexprtokenlist[
                    return_expr_root_token.Id]

            f.return_units = []  #return_units
            f.arg_units = []  #arg_units
            f.return_arg_var_nr = return_arg_var_nr
            f.return_expr_root_token = return_expr_root_token
            f.is_unit_propagation_based_on_constants = is_unit_propagation_based_on_constants
            f.is_unit_propagation_based_on_unknown_variable = is_unit_propagation_based_on_unknown_variable
            f.is_unit_propagation_based_on_weak_inference = is_unit_propagation_based_on_weak_inference
            f.maybe_generic_function = maybe_generic_function
            for arg_number in f.argument.keys():
                f.arg_units.append([])

        # collect return units of all functions
        returnlist = {}

        for function_dict in sorted_analysis_unit_dict.values():
            if not function_dict['scopeObject'].function:
                continue
            if function_dict['scopeObject'].function.return_arg_var_nr:
                continue
            if function_dict['scopeObject'].function.maybe_generic_function:
                continue

            returnlist[function_dict['scopeObject'].function.Id] = []

            for root_token in function_dict['root_tokens']:
                if root_token.str == 'return':
                    t = returntokenlist[root_token.Id]

                    self.check_error_when_top3_units(t)

                    #RETURN STATEMENT WITH UNITS - STORE UNITS
                    if t.units:
                        for u in t.units:
                            if u not in returnlist[
                                    function_dict['scopeObject'].function.Id]:
                                returnlist[function_dict['scopeObject'].
                                           function.Id].append(u)

                    tw = TreeWalker(None)
                    tw.generic_recurse_and_apply_function(t, tw.reset_tokens)

        for f in c.functions:
            return_units = returnlist.get(f.Id)
            if return_units:
                f.return_units = return_units

        # check all errors
        for e in self.all_errors:
            con.FOUND_DERIVED_CU_VARIABLE = False

            if e.is_warning:
                continue

            if e.dont_check_for_warning:
                continue

            if e.ERROR_TYPE == UnitErrorTypes.ADDITION_OF_INCOMPATIBLE_UNITS or \
                    e.ERROR_TYPE == UnitErrorTypes.COMPARISON_INCOMPATIBLE_UNITS:

                root_token = None
                # find token in the copy
                for t in c.tokenlist:
                    if t.Id == e.token.Id:
                        root_token = t
                        break
                if not root_token:
                    continue

                self.check_error_when_top3_units(root_token)

                if e.ERROR_TYPE == UnitErrorTypes.ADDITION_OF_INCOMPATIBLE_UNITS:
                    if con.FOUND_DERIVED_CU_VARIABLE:
                        if len(root_token.units) > 2:
                            e.is_warning = True
                    elif root_token.units:
                        e.is_warning = True

                else:
                    units = []
                    if root_token.astOperand1 and root_token.astOperand2:
                        left_units = root_token.astOperand1.units
                        right_units = root_token.astOperand2.units
                        if not left_units:
                            pass  #units = right_units
                        elif not right_units:
                            pass  #units = left_units
                        else:
                            for lu in left_units:
                                if lu in right_units:
                                    units.append(lu)

                    if con.FOUND_DERIVED_CU_VARIABLE:
                        if len(units) > 2:
                            e.is_warning = True
                    elif units:
                        e.is_warning = True

                tw = TreeWalker(None)
                tw.generic_recurse_and_apply_function(root_token,
                                                      tw.reset_tokens)

            elif e.ERROR_TYPE == UnitErrorTypes.VARIABLE_MULTIPLE_UNITS:

                i = 0
                root_token = None
                left_token = None
                # find token in the copy
                for t in c.tokenlist:
                    if t.Id == e.token.Id:
                        root_token = t
                        i = i + 1
                    elif t.Id == e.token_left.Id:
                        left_token = t
                        i = i + 1
                    if i == 2:
                        break
                if (not root_token) or (not left_token):
                    continue
                elif not root_token.astOperand2:
                    continue
                elif not root_token.astOperand1:
                    continue

                self.check_error_when_top3_units(root_token.astOperand1)
                self.check_error_when_top3_units(root_token.astOperand2)

                if (not left_token.isKnown
                    ):  #and root_token.astOperand2.units:
                    if con.FOUND_DERIVED_CU_VARIABLE:
                        if len(root_token.astOperand2.units) > 2:
                            e.is_warning = True
                    elif root_token.astOperand2.units:
                        e.is_warning = True
                else:
                    if root_token.astOperand2.units and (
                            root_token.astOperand1.units
                            == root_token.astOperand2.units):
                        e.is_warning = True

                    if (not e.is_warning) and (
                            root_token.astOperand1.
                            is_unit_propagation_based_on_weak_inference):
                        units = []
                        for lu in root_token.astOperand1.units:
                            if lu in root_token.astOperand2.units:
                                units.append(lu)

                        if con.FOUND_DERIVED_CU_VARIABLE:
                            if len(units) > 2:
                                e.is_warning = True
                        elif units:
                            e.is_warning = True

                    #if not con.is_df_constraint_present(e.token_left, e.var_name):
                    #    if root_token.astOperand2.units: #and (root_token.astOperand1.units == root_token.astOperand2.units):
                    #        units = []
                    #        for lu in root_token.astOperand1.units:
                    #            if lu in root_token.astOperand2.units:
                    #                units.append(lu)

                    #        if con.FOUND_DERIVED_CU_VARIABLE:
                    #            if len(units) > 2:
                    #                e.is_warning = True
                    #        elif units:
                    #            e.is_warning = True

                tw = TreeWalker(None)
                tw.generic_recurse_and_apply_function(root_token,
                                                      tw.reset_tokens)
Esempio n. 13
0
    def get_left_right_units(self, token, left_token, right_token):
        units = []
        left_units = []
        right_units = []

        if left_token:
            if left_token.str in [
                    '*', '/'
            ] and left_token.astOperand1 and left_token.astOperand2:
                if left_token.astOperand1.units == [{'nounit': 0.0}]:
                    left_token = left_token.astOperand2
                elif left_token.astOperand2.units == [{'nounit': 0.0}]:
                    left_token = left_token.astOperand1

            if left_token.str in ['+', '-', '*', '/']:
                left_units = self.get_left_right_units(left_token,
                                                       left_token.astOperand1,
                                                       left_token.astOperand2)
            else:
                left_units = left_token.units
                left_name = left_token.str
                if left_token.str == '.' or left_token.str == '[':
                    (
                        left_token, left_name
                    ) = self.symbol_helper.find_compound_variable_and_name_for_dot_operand(
                        left_token)

                if (left_token.variable, left_name) in con.variable2unitproba:
                    n = 3
                    if con.is_only_known_unit_variable(left_token.variable,
                                                       left_name):
                        n = 1
                    left_units = con.variable2unitproba[(left_token.variable,
                                                         left_name)][:n]
                    left_units = filter(
                        lambda (u, p): p > con.unit_prob_threshold, left_units)
                    left_units = map(lambda (u, p): u, left_units)
                    if con.ENABLE_UNIT_LIST_FLATTENING:
                        left_units = con.flatten_unit_list(left_units)

        if right_token:
            if right_token.str in [
                    '*', '/'
            ] and right_token.astOperand1 and right_token.astOperand2:
                if right_token.astOperand1.units == [{'nounit': 0.0}]:
                    right_token = right_token.astOperand2
                elif right_token.astOperand2.units == [{'nounit': 0.0}]:
                    right_token = right_token.astOperand1

            if right_token.str in ['+', '-', '*', '/']:
                right_units = self.get_left_right_units(
                    right_token, right_token.astOperand1,
                    right_token.astOperand2)
            else:
                right_units = right_token.units
                right_name = right_token.str
                if right_token.str == '.' or right_token.str == '[':
                    (
                        right_token, right_name
                    ) = self.symbol_helper.find_compound_variable_and_name_for_dot_operand(
                        right_token)

                if (right_token.variable,
                        right_name) in con.variable2unitproba:
                    n = 3
                    if con.is_only_known_unit_variable(right_token.variable,
                                                       right_name):
                        n = 1
                    right_units = con.variable2unitproba[(right_token.variable,
                                                          right_name)][:n]
                    right_units = filter(
                        lambda (u, p): p > con.unit_prob_threshold,
                        right_units)
                    right_units = map(lambda (u, p): u, right_units)
                    if con.ENABLE_UNIT_LIST_FLATTENING:
                        right_units = con.flatten_unit_list(right_units)

        if not left_units:
            return right_units
        elif not right_units:
            return left_units
        else:
            if token.str in ['*', '/']:
                tw = TreeWalker(None)
                all_unit_dicts_from_multiplication = []
                for unit_dict_left in left_units:
                    for unit_dict_right in right_units:
                        result_units = tw.apply_multiplication_to_unit_dicts(
                            unit_dict_left, unit_dict_right, token.str)
                        if result_units:
                            all_unit_dicts_from_multiplication.append(
                                result_units)
                for u in all_unit_dicts_from_multiplication:
                    if u not in units:
                        units.append(u)
            else:
                for lu in left_units:
                    if lu in right_units:
                        units.append(lu)

        return units
Esempio n. 14
0
    def analyze_function(self, function_dict):

        if self.debug_verbose:
            print inspect.stack()[0][3]
        tw = TreeWalker(
            function_dict
        )  # ARGUMENT 'FUNCTION DICTIONARY' IS USED BY SYMBOL TABLE
        tw.cps_unit_checker = self
        tw.my_symbol_helper.cps_unit_checker = self
        self.tw = tw  # LINK CURRENT Tree Walker to self
        tw.debug = self.debug
        tw.debug_verbose = self.debug_verbose
        tw.current_file = self.current_file_under_analysis
        tw.source_file_lines = self.source_file_lines
        tw.source_file = self.source_file
        tw.should_check_unitless_during_multiplication = False  # UNITLESS
        tw.my_symbol_helper.should_match_on_heuristic_variable_names = False
        tw.current_function_dict = function_dict

        found_units_in_this_function = False

        # ASSUME THE TOKENS COME BACK AS A SORTED LIST
        break_point = 1000
        i = 0

        for root_token in function_dict['root_tokens']:
            # INITIALIZAE TREE WALKER FOR THIS ROOT TOKEN
            tw.was_some_unit_changed = True
            tw.is_unit_propagation_based_on_constants = False
            tw.is_unit_propagation_based_on_unknown_variable = False
            if self.SHOULD_ONLY_FIND_FILES_WITH_UNITS and self.found_ros_units_in_this_file and not self.SHOULD_FIND_ALL_UNITS:
                return
            # RESET THE TREE WALKER'S LINE NUMBERS
            tw.reset_min_max_line_numbers()
            # FIND THE MIN AND MAX LINE NUMBERS IN THIS AST : USED TO PROTECT LOOP FROM MULTI-LINE STATEMENTS
            tw.generic_recurse_and_apply_function(root_token,
                                                  tw.find_min_max_line_numbers)

            # APPLY ROS UNITS TO VARIABLES
            tw.generic_recurse_and_apply_function(root_token,
                                                  tw.apply_ROS_units)
            # APPLY UNITS FROM PREVIOUS ASSIGNMENTS IN SCOPE
            tw.generic_recurse_and_apply_function(root_token,
                                                  tw.apply_units_from_scope)
            # APPLY UNITS FROM KNOWN FUNCTIONS - atan2
            tw.generic_recurse_and_apply_function(root_token,
                                                  tw.apply_units_inverse_trig)
            # APPLY UNITS FROM KNOWN SYMBOLS - M_PI
            tw.generic_recurse_and_apply_function(root_token,
                                                  tw.apply_units_known_symbols)
            # APPLY UNITS FROM KNOWN FUNCTION - toSec
            tw.generic_recurse_and_apply_function(root_token,
                                                  tw.apply_units_toSec)
            # APPLY UNITS FROM KNOWN FUNCTION - getX, getY, getZ
            tw.generic_recurse_and_apply_function(root_token,
                                                  tw.apply_units_getXYZ)
            # APPLY UNITS FROM KNOWN FUNCTION - quatToRPY
            tw.generic_recurse_and_apply_function(root_token,
                                                  tw.apply_units_quatToRPY)

            # CONTINUE TO ATTEMPT CHANGES UNTIL CHANGES CEASE
            while tw.was_some_unit_changed:
                if i > break_point:
                    if self.debug_verbose:
                        s = "BREAKING QUIESSENCE (WHILE) LOOP AT %d" % break_point
                        raise ValueError(s)
                        return
                    break
                i += 1
                tw.was_some_unit_changed = False
                # LOOK FOR EARLY ABANDONMENT OF THIS AST
                if not tw.found_units_in_this_tree and self.should_abandon_early:
                    break
                # SPECIAL MODE - JUST FIND ROS FILES
                if self.SHOULD_ONLY_FIND_FILES_WITH_UNITS:
                    break
                ### PROPAGATE ACROSS '.'
                tw.generic_recurse_and_apply_function(
                    root_token, tw.propagate_units_across_dot_connectors)
                ### PROPAGATE ACROSS + - * /  += -= *= /=
                tw.generic_recurse_and_apply_function(
                    root_token, tw.propagate_units_across_operators)
                ### PROPAGATE ACROSS (
                tw.generic_recurse_and_apply_function(
                    root_token, tw.propagate_units_across_parenthesis)
                ### PROPAGATE ACROSS [
                tw.generic_recurse_and_apply_function(
                    root_token, tw.propagate_units_across_square_brackets)
                ### PROPAGATE INTO f(meters, arg2)  into function  - FUTURE: CONSTRAINT MODE
                #tw.generic_recurse_and_apply_function(root_token, tw.propagate_units_into_function_args)
                ### PROPAGATE ACROSS '='
                tw.generic_recurse_and_apply_function(
                    root_token, tw.propagate_units_across_assignment)
                ### PROPAGATE ACROSS 'std::abs' 'std::fabs' 'abs' 'fabs'
                tw.generic_recurse_and_apply_function(
                    root_token, tw.propagate_units_math_abs_fabs_floor_ceil)
                ### PROPAGATE ACROSS 'std::min' 'std::max' 'min' 'max'
                tw.generic_recurse_and_apply_function(
                    root_token, tw.propagate_units_math_min_max)
                ### PROPAGATE ACROSS 'sqrt'
                tw.generic_recurse_and_apply_function(root_token,
                                                      tw.propagate_units_sqrt)
                ### PROPAGATE ACROSS 'getXYZ
                # tw.generic_recurse_and_apply_function(root_token, tw.propagate_units_getXYZ)
                ### PROPAGATE ACROSS TERNARY
                tw.generic_recurse_and_apply_function(
                    root_token, tw.propagate_units_ternary)
                ### PROPAGATE ACROSS 'pow'
                tw.generic_recurse_and_apply_function(root_token,
                                                      tw.propagate_units_pow)
                ### PROPAGATE ACROSS 'atan2', 'acos', 'asin'
                tw.generic_recurse_and_apply_function(
                    root_token, tw.propagate_units_inverse_trig)
                ### PROPAGATE ACROSS 'return'
                tw.generic_recurse_and_apply_function(
                    root_token, tw.propagate_units_across_return)
                ### COLLECT UNITS FROM FUNCTION CALL POINTS
                tw.generic_recurse_and_apply_function(
                    root_token, tw.
                    collect_function_parameters_units_and_decorate_function_objects
                )
                #FUNCTIONS todo:
            # END -- WHILE LOOP
            #ASSIGNMENT STATEMENTS WITH UNITS - RIGHT TO LEFT PROPAGATION
            if root_token.isAssignmentOp and root_token.units:
                # COLLECT LEFT SIDE OF ASSIGNMENT
                lhs_compound_name = tw.recurse_and_collect_string(
                    root_token.astOperand1)
                # ADD UNITS TO VARIABLE IN SCOPE
                tw.return_value_list = []
                tw.generic_recurse_and_apply_function(root_token.astOperand1,
                                                      tw.find_first_variable)
                if len(tw.return_value_list) != 1:
                    if len(tw.return_value_list) == 0:
                        if self.debug and self.debug_LHS:
                            print "%s %s LHS no variable found not found" % (
                                root_token.file, root_token.linenr)
                    else:
                        if self.debug and self.debug_LHS:
                            for value in tw.return_value_list:
                                print "%s %s LHS Variable found: %s" % (
                                    root_token.file, root_token.linenr, value)
                    continue  # todo track count of this error
                lhs_var = tw.return_value_list[0]
                lhs_scope = lhs_var.nameToken.scope
                if lhs_var.isArgument:
                    lhs_scope = function_dict['scopeObject']

                line_num = int(root_token.linenr)
                if lhs_compound_name in lhs_scope.var_ordered_dict:
                    # ALREADY HAS ASSIGNMENT, ADD TO IT
                    lhs_scope.var_ordered_dict[lhs_compound_name][line_num] = {
                        'units':
                        root_token.units,  # THIS IS A LIST 
                        'token':
                        root_token,
                        'is_unit_propagation_based_on_constants':
                        tw.is_unit_propagation_based_on_constants,
                        'is_unit_propagation_based_on_unknown_variable':
                        tw.is_unit_propagation_based_on_unknown_variable
                    }
                else:
                    lhs_scope.var_ordered_dict[lhs_compound_name] = {
                        line_num: {
                            'units':
                            root_token.units,
                            'token':
                            root_token,
                            'is_unit_propagation_based_on_constants':
                            tw.is_unit_propagation_based_on_constants,
                            'is_unit_propagation_based_on_unknown_variable':
                            tw.is_unit_propagation_based_on_unknown_variable
                        }
                    }

                if self.debug and self.debug_scope:
                    print "ADDED to SCOPE %s : %s has units %s at %s" % (
                        lhs_scope.Id, lhs_compound_name, root_token.units,
                        line_num)
                    print 'constants-based? %s  unknown-based? %s' % (
                        tw.is_unit_propagation_based_on_constants,
                        tw.is_unit_propagation_based_on_unknown_variable)
            # EXTRACT UNITS FROM RETURN STATEMENT AND APPLY TO FUNCTION
            if root_token.str == 'return' and root_token.units:
                if function_dict['scopeObject'].function:
                    function_return_units = function_dict[
                        'scopeObject'].function.return_units
                    for u in root_token.units:
                        if u not in function_return_units:
                            function_return_units.append(u)
                            function_dict[
                                'scopeObject'].function.is_unit_propagation_based_on_constants = tw.is_unit_propagation_based_on_constants
                            function_dict[
                                'scopeObject'].function.is_unit_propagation_based_on_unknown_variable = tw.is_unit_propagation_based_on_unknown_variable
            found_units_in_this_function = found_units_in_this_function or tw.found_units_in_this_tree

        # LOOK FOR EARLY ABANDONMENT
        if not found_units_in_this_function and not self.debug_print_AST and self.should_abandon_early:
            return

        # DEBUG PRINTING
        for root_token in function_dict['root_tokens']:
            if self.debug_print_AST:
                tw.debug_walk(root_token)

        self.found_ros_units_in_this_file = self.found_ros_units_in_this_file or found_units_in_this_function