blob: 451fe28d1cd3b68a8642d3279b2fcbf3a3dd150d [file] [log] [blame]
Mike Dodd8cfa7022010-11-17 11:12:26 -08001/**
2 * @file symbol_sort.cpp
3 * Sorting symbols
4 *
5 * @remark Copyright 2002, 2003 OProfile authors
6 * @remark Read the file COPYING
7 *
8 * @author Philippe Elie
9 * @author John Levon
10 */
11
12#include "symbol_sort.h"
13#include "symbol_functors.h"
14
15#include "name_storage.h"
16#include "op_exception.h"
17
18#include <algorithm>
19#include <sstream>
20
21using namespace std;
22
23namespace {
24
25bool long_filenames;
26
27int image_compare(image_name_id l, image_name_id r)
28{
29 if (long_filenames)
30 return image_names.name(l).compare(image_names.name(r));
31 return image_names.basename(l).compare(image_names.basename(r));
32}
33
34
35int debug_compare(debug_name_id l, debug_name_id r)
36{
37 if (long_filenames)
38 return debug_names.name(l).compare(debug_names.name(r));
39 return debug_names.basename(l).compare(debug_names.basename(r));
40}
41
42
43int compare_by(sort_options::sort_order order,
44 symbol_entry const & lhs, symbol_entry const & rhs)
45{
46 switch (order) {
47 case sort_options::sample:
48 if (lhs.sample.counts[0] < rhs.sample.counts[0])
49 return 1;
50 if (lhs.sample.counts[0] > rhs.sample.counts[0])
51 return -1;
52 return 0;
53
54 case sort_options::symbol:
55 return symbol_names.demangle(lhs.name).compare(
56 symbol_names.demangle(rhs.name));
57
58 case sort_options::image:
59 return image_compare(lhs.image_name, rhs.image_name);
60
61 case sort_options::app_name:
62 return image_compare(lhs.app_name, rhs.app_name);
63
64 case sort_options::vma:
65 if (lhs.sample.vma < rhs.sample.vma)
66 return -1;
67 if (lhs.sample.vma > rhs.sample.vma)
68 return 1;
69 return 0;
70
71 case sort_options::debug: {
72 file_location const & f1 = lhs.sample.file_loc;
73 file_location const & f2 = rhs.sample.file_loc;
74 int ret = debug_compare(f1.filename, f2.filename);
75 if (ret == 0)
76 ret = f1.linenr - f2.linenr;
77 return ret;
78 }
79
80 default: {
81 // static_cast<> to shut up g++ 2.91.66 which warn
82 // about ambiguity between <<(int) and <<(long int)
83 ostringstream os;
84 os << "compare_by(): unknown sort option: "
85 << static_cast<int>(order) << endl;
86 throw op_fatal_error(os.str());
87 }
88 }
89
90 return 0;
91}
92
93
94struct symbol_compare {
95 symbol_compare(vector<sort_options::sort_order> const & order,
96 bool reverse)
97 : compare_order(order), reverse_sort(reverse) {}
98
99 bool operator()(symbol_entry const * lhs,
100 symbol_entry const * rhs) const {
101 return operator()(*lhs, *rhs);
102 }
103
104 bool operator()(symbol_entry const & lhs,
105 symbol_entry const & rhs) const;
106
107protected:
108 vector<sort_options::sort_order> const & compare_order;
109 bool reverse_sort;
110};
111
112
113bool symbol_compare::operator()(symbol_entry const & lhs,
114 symbol_entry const & rhs) const
115{
116 for (size_t i = 0; i < compare_order.size(); ++i) {
117 int ret = compare_by(compare_order[i], lhs, rhs);
118
119 if (reverse_sort)
120 ret = -ret;
121 if (ret != 0)
122 return ret < 0;
123 }
124 return false;
125}
126
127
128} // anonymous namespace
129
130
131void sort_options::
132sort(symbol_collection & syms, bool reverse_sort, bool lf) const
133{
134 long_filenames = lf;
135
136 vector<sort_order> sort_option(options);
137 for (sort_order cur = first; cur != last; cur = sort_order(cur + 1)) {
138 if (find(sort_option.begin(), sort_option.end(), cur) ==
139 sort_option.end())
140 sort_option.push_back(cur);
141 }
142
143 stable_sort(syms.begin(), syms.end(),
144 symbol_compare(sort_option, reverse_sort));
145}
146
147
148void sort_options::
149sort(diff_collection & syms, bool reverse_sort, bool lf) const
150{
151 long_filenames = lf;
152
153 vector<sort_order> sort_option(options);
154 for (sort_order cur = first; cur != last; cur = sort_order(cur + 1)) {
155 if (find(sort_option.begin(), sort_option.end(), cur) ==
156 sort_option.end())
157 sort_option.push_back(cur);
158 }
159
160 stable_sort(syms.begin(), syms.end(),
161 symbol_compare(sort_option, reverse_sort));
162}
163
164
165void sort_options::add_sort_option(string const & name)
166{
167 if (name == "vma") {
168 options.push_back(vma);
169 } else if (name == "sample") {
170 options.push_back(sample);
171 } else if (name == "symbol") {
172 options.push_back(symbol);
173 } else if (name == "debug") {
174 options.push_back(debug);
175 } else if (name == "image") {
176 options.push_back(image);
177 } else if (name == "app-name") {
178 options.push_back(app_name);
179 } else {
180 ostringstream os;
181 os << "unknown sort option: " << name << endl;
182 throw op_fatal_error(os.str());
183 }
184}
185
186
187void sort_options::add_sort_option(sort_options::sort_order order)
188{
189 options.push_back(order);
190}