<commit_before>__author__ = 'kevin'

import re

from attacksurfacemeter.call import Call


class GprofCall(Call):
    """
        Represents a function/method call in a source code.

        Encapsulates parsing logic for gprof's output.
        For each new line of output, an instance of this class is created.
    """
    def __init__(self, line):
        """
            Call constructor.

            Receives a line of gprof's output and parses it for some key information such as
            function name and the point where it's defined.

            Args:
                line: A String containing one single line of raw information output from gprof.

            Returns:
                A new instance of Call.

            Sample lines:
                                0.00    0.00  131072/147456      get_bits (get_bits.h:262 @ 6d16df) [269306]
                [4]      0.0    0.00    0.00  147456         read_tree (bink.c:245 @ 7003f0) [4]
        """
        self.raw_line = line
        match = re.search(r"(\[\d+\])( +)((\d+\.\d+)( +)){3}(\d*)( +)([\w.]+)( +)(.*)", line)

        if not match:
            match = re.search(r"(\[\d+)( +)((\d+\.\d+)( +)){3}(\d*)( +)([\w.]+)( +)(.*)", line)

        if match:
            self._function_name = match.group(8)
            self._function_signature = self.get_file_name(match.group(10))
        else:
            match = re.search(r"( +)((\d+\.\d+)( +)){2}(\d+/\d+)( +)([\w.]+)( +)(.*)", line)

            if match:
                self._function_name = match.group(7)
                self._function_signature = self.get_file_name(match.group(9))
            else:
                match = re.search(r"( +)(\d+)( +)(\w+)( +)(.*)", line)

                if match:
                    try:
                        self._function_name = match.group(4)
                        self._function_signature = self.get_file_name(match.group(6))
                    except:
                        raise ValueError("Can not parse a call from the received text.")
                else:
                    raise ValueError("Can not parse a call from the received text.")

    def get_file_name(self, text_fragment):
        """
            Obtains the name of the file where the function represented is defined.

            Args:
               text_fragment: A String containing a fragment from a line of gprof's output.<commit_msg>Modified parsing regexes to handle new special case of grpof output. Added comments with sample output for future reference.<commit_after>__author__ = 'kevin'

import re

from attacksurfacemeter.call import Call


class GprofCall(Call):
    """
        Represents a function/method call in a source code.

        Encapsulates parsing logic for gprof's output.
        For each new line of output, an instance of this class is created.
    """
    def __init__(self, line):
        """
            Call constructor.

            Receives a line of gprof's output and parses it for some key information such as
            function name and the point where it's defined.

            Args:
                line: A String containing one single line of raw information output from gprof.

            Returns:
                A new instance of Call.

            Sample lines:
                                0.00    0.00  131072/147456      get_bits (get_bits.h:262 @ 6d16df) [269306]
                [4]      0.0    0.00    0.00  147456         read_tree (bink.c:245 @ 7003f0) [4]

            Some identified special cases:
                [28]     0.0    0.00    0.00      58+8       avg_cavs_qpel8or16_v1_3dnow (cavsdsp_mmx.c:429 @ 9afb10) [28]'
                [18977   0.0    0.00    0.00                 ff_choose_timebase (mux.c:106 @ 54fd80) [189777]
        """
        self.raw_line = line
        match = re.search(r"(\[\d+\])( +)((\d+\.\d+)( +)){3}(\d*\+*\d*)( +)([\w.]+)( +)(.*)", line)

        if not match:
            match = re.search(r"(\[\d+)( +)((\d+\.\d+)( +)){3}(\d*)( +)([\w.]+)( +)(.*)", line)

        if match:
            self._function_name = match.group(8)
            self._function_signature = self.get_file_name(match.group(10))
        else:
            match = re.search(r"( +)((\d+\.\d+)( +)){2}(\d+/\d+)( +)([\w.]+)( +)(.*)", line)

            if match:
                self._function_name = match.group(7)
                self._function_signature = self.get_file_name(match.group(9))
            else:
                match = re.search(r"( +)(\d+)( +)(\w+)( +)(.*)", line)

                if match:
                    try:
                        self._function_name = match.group(4)
                        self._function_signature = self.get_file_name(match.group(6))
                    except:
                        raise ValueError("Can not parse a call from the received text.")
                else:
                    raise ValueError("Can not parse a call from the received text.")

    def get_file_name(self, text_fragment):
        """
            Obtains the name of the file where the function represented is defined.

            Args:
               text_fragment: A String containing a fragment from a line of gprof's output.
{'fraction_non_alphanumeric': 0.12966183574879228, 'fraction_numerical': 0.034782608695652174, 'mean_word_length': 1.6036217303822937, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '103873', 'n_tokens_mistral': 1638, 'n_tokens_neox': 1476, 'n_words': 442}