1#!/usr/bin/python
2#
3# Copyright 2017, Data61
4# Commonwealth Scientific and Industrial Research Organisation (CSIRO)
5# ABN 41 687 119 230.
6#
7# This software may be distributed and modified according to the terms of
8# the BSD 2-Clause license. Note that NO WARRANTY is provided.
9# See "LICENSE_BSD2.txt" for details.
10#
11# @TAG(DATA61_BSD)
12#
13
14#
15# A simple script to extract the results that you care
16# about from the benchmarking output into nicely parsed xml.
17# Yes it is horrible
18# and depends totally on the format of that output.
19#
20#
21# Usage:
22# ./fitler-results file-with-results-to-select file-with-results
23#
24# Example entry for a result to select:
25#
26# Name of result 98 -> 100 1 wait_func send_func
27#
28# Format of file-with-results-to-select:
29#
30#  $0    $1      $2      $3       $4       $5             $6
31# (.*) ([0-9]+) (->|<-) ([0-9]+) ([0-9]+) ([A-Za-z_]+) ([A-Za-z_]+)
32#
33# $0: the name of this result (you invent it)
34# $1 The first priority
35# $2 the direction of the call
36# $3 the second priority
37# $4 the length of the message
38# $5 the name of the first priorities function
39# $6 the name of the second priorities function
40#
41# Format of the file-with-results
42#
43# Entries should look like this (spaces don't matter):
44#
45# 98 -> 100, Length 1:
46#     wait_func:
47#         CCNT: 3667
48#         PMC0: 0
49#         PMC1: 47
50#     send_func:
51#         CCNT: 3667
52#         PMC0: 0
53#         PMC1: 47
54#
55# Currently only the first result is extracted.
56
57import re
58import sys
59import pdb
60
61selectionsFile = open(sys.argv[1], 'r')
62results = open(sys.argv[2], 'r')
63
64selectionRegexp = re.compile('(.*) ([0-9]+) (->|<-) ([0-9]+) ([0-9]+) ([A-Za-z_]+) ([A-Za-z_]+)')
65
66
67class Selection:
68    name = ""
69    firstPriority = ""
70    direction = ""
71    secondPriority = ""
72    length = 0
73    firstFunction = ""
74    secondFunction = ""
75
76    def match(self, other):
77        return (self.firstPriority == other.firstPriority and
78                self.direction == other.direction and
79                self.secondPriority == other.secondPriority and
80                self.length == other.length and
81                self.firstFunction == other.firstFunction and
82                self.secondFunction == other.secondFunction)
83
84
85# this is the list of all of the results we want to select
86selections = []
87
88# parse the selections
89for line in selectionsFile:
90    match = selectionRegexp.match(line.rstrip())
91    if match is None:
92        print "Invalid selection on line {0} of file {1}".format(line, sys.argv[1])
93        exit
94
95    selection = Selection()
96    selection.name = match.group(1)
97    selection.firstPriority = match.group(2)
98    selection.direction = match.group(3)
99    selection.secondPriority = match.group(4)
100    selection.length = match.group(5)
101    selection.firstFunction = match.group(6)
102    selection.secondFunction = match.group(7)
103   # pdb.set_trace()
104
105    selections.append(selection)
106
107print "<results>"
108
109entryStartRegexp = re.compile('([0-9]+) (<-|->) ([0-9]+), Length ([0-9]+):')
110
111# iterate through every result and look for our selections. Bail early if
112# we find them all.
113#
114# complexity of this loop is O(nxm) where n is the number of selections and
115# m is the number of entries in the results file.
116line = results.readline()
117while len(line) > 0 and len(selections) > 0:
118    match = entryStartRegexp.match(line.rstrip())
119    if match is not None:
120        candidate = Selection()
121        candidate.firstPriority = match.group(1)
122        candidate.direction = match.group(2)
123        candidate.secondPriority = match.group(3)
124        candidate.length = match.group(4)
125        candidate.firstFunction = results.readline().strip().strip(':')
126        count = int(results.readline().strip().split(' ')[1])
127        results.readline()  # PMC0
128        results.readline()  # PMC1
129        candidate.secondFunction = results.readline().strip().strip(':')
130        # try to match each of our selections against the one we have just parsed
131        matched = None
132        for selection in selections:
133           # pdb.set_trace()
134            if (selection.match(candidate)):
135                print "<result name=\"{0}\">".format(selection.name)
136                print count
137                print "</result>"
138                matched = selection
139                break
140
141        # we found this selection, don't bother searching for it anymore
142        if matched is not None:
143            selections.remove(matched)
144
145    line = results.readline()
146
147print "</results>"
148