@@ -0,0 +1,2702 @@
+#!/usr/bin/python3%0A%22%22%22%0Ausage: color_sample.py %5B-h%5D %5Bfile%5D%0A%0AColor a call tree file generated by sample%0A%0Apositional arguments:%0A  file        sample file%0A%0Aoptional arguments:%0A  -h, --help  show this help message and exit%0A%22%22%22%0A%0Aimport re%0Aimport argparse%0Aimport fileinput%0Aimport bisect%0A%0AEND_MARKER = 'Total number in stack'%0ABEGIN_MARKER = 'Call graph:'%0AREGEX = re.compile(r'%5E%5CD*(%5Cd+)')%0A%0A%0Adef fg(r, g, b):%0A    %22%22%22Change foreground color.%22%22%22%0A    return '%5C033%5B38;2;%7B:d%7D;%7B:d%7D;%7B:d%7Dm'.format(r, g, b)%0A%0A%0Adef reset():%0A    %22%22%22Reset foreground color.%22%22%22%0A    return '%5C033%5B0m'%0A%0A%0Adef rgb(minimum, maximum, value):%0A    %22%22%22Convert value within range to RGB.%22%22%22%0A    assert value %3C= maximum%0A    assert value %3E= minimum%0A    minimum, maximum = float(minimum), float(maximum)%0A    r = 2 * (value - minimum) / (maximum - minimum)%0A    b = int(max(0, 255 * (1 - r)))%0A    r = int(max(0, 255 * (r - 1)))%0A    g = 255 - b - r%0A    return r, g, b%0A%0A%0Adef binary_find(a, x):%0A    %22%22%22Find value in sorted list.%22%22%22%0A    i = bisect.bisect_left(a, x)%0A    if i != len(a) and a%5Bi%5D == x:%0A        return i%0A    return -1%0A%0A%0Adef get_all_samples(lines):%0A    %22%22%22Compute a list of all samples.%22%22%22%0A    parsing = False%0A    samples = %5B%5D%0A    for line in lines:%0A        if BEGIN_MARKER in line:%0A            parsing = True%0A            continue%0A%0A        if END_MARKER in line:%0A            break%0A%0A        if not parsing:%0A            continue%0A%0A        match = re.match(REGEX, line)%0A        if not match:%0A            continue%0A%0A        samples.append(int(match.group(1)))%0A%0A    return sorted(set(samples))%0A%0A%0Adef color(lines, all_samples):%0A    %22%22%22Color the call tree based on the amount of samples for each branch.%22%22%22%0A    minimum = 0%0A    maximum = len(all_samples)%0A    coloring = False%0A    for line in lines:%0A        if BEGIN_MARKER in line:%0A            coloring = True%0A%0A        if END_MARKER in line:%0A            coloring = False%0A%0A        if not coloring:%0A            print(line)%0A            continue%0A%0A        match = re.match(REGEX, line)%0A        if not match:%0A            print(line)%0A            continue%0A%0A        samples = int(match.group(1))%0A        value = binary_find(all_samples, samples)%0A        r, g, b = rgb(minimum, maximum, value)%0A        print(fg(r, g, b) + line + reset())%0A%0A%0Adef main():%0A    %22%22%22Color a call tree file generated by sample.%22%22%22%0A    parser = argparse.ArgumentParser(%0A        description='Color a call tree file generated by sample')%0A    parser.add_argument('file', nargs='?', help='sample file')%0A    args = parser.parse_args()%0A%0A    with fileinput.input(args.file) as file:%0A        lines = %5B%5D%0A        for line in file:%0A            lines.append(line.rstrip())%0A        color(lines, get_all_samples(lines))%0A%0A%0Aif __name__ == %22__main__%22:%0A    main()%0A

Add color_sample.py