symbol_sort.cpp
Go to the documentation of this file.00001
00012 #include "symbol_sort.h"
00013 #include "symbol_functors.h"
00014
00015 #include "name_storage.h"
00016 #include "op_exception.h"
00017
00018 #include <algorithm>
00019 #include <sstream>
00020
00021 using namespace std;
00022
00023 namespace {
00024
00025 bool long_filenames;
00026
00027 int image_compare(image_name_id l, image_name_id r)
00028 {
00029 if (long_filenames)
00030 return image_names.name(l).compare(image_names.name(r));
00031 return image_names.basename(l).compare(image_names.basename(r));
00032 }
00033
00034
00035 int debug_compare(debug_name_id l, debug_name_id r)
00036 {
00037 if (long_filenames)
00038 return debug_names.name(l).compare(debug_names.name(r));
00039 return debug_names.basename(l).compare(debug_names.basename(r));
00040 }
00041
00042
00043 int compare_by(sort_options::sort_order order,
00044 symbol_entry const & lhs, symbol_entry const & rhs)
00045 {
00046 switch (order) {
00047 case sort_options::sample:
00048 if (lhs.sample.counts[0] < rhs.sample.counts[0])
00049 return 1;
00050 if (lhs.sample.counts[0] > rhs.sample.counts[0])
00051 return -1;
00052 return 0;
00053
00054 case sort_options::symbol:
00055 return symbol_names.demangle(lhs.name).compare(
00056 symbol_names.demangle(rhs.name));
00057
00058 case sort_options::image:
00059 return image_compare(lhs.image_name, rhs.image_name);
00060
00061 case sort_options::app_name:
00062 return image_compare(lhs.app_name, rhs.app_name);
00063
00064 case sort_options::vma:
00065 if (lhs.sample.vma < rhs.sample.vma)
00066 return -1;
00067 if (lhs.sample.vma > rhs.sample.vma)
00068 return 1;
00069 return 0;
00070
00071 case sort_options::debug: {
00072 file_location const & f1 = lhs.sample.file_loc;
00073 file_location const & f2 = rhs.sample.file_loc;
00074 int ret = debug_compare(f1.filename, f2.filename);
00075 if (ret == 0)
00076 ret = f1.linenr - f2.linenr;
00077 return ret;
00078 }
00079
00080 default: {
00081
00082
00083 ostringstream os;
00084 os << "compare_by(): unknown sort option: "
00085 << static_cast<int>(order) << endl;
00086 throw op_fatal_error(os.str());
00087 }
00088 }
00089
00090 return 0;
00091 }
00092
00093
00094 struct symbol_compare {
00095 symbol_compare(vector<sort_options::sort_order> const & order,
00096 bool reverse)
00097 : compare_order(order), reverse_sort(reverse) {}
00098
00099 bool operator()(symbol_entry const * lhs,
00100 symbol_entry const * rhs) const {
00101 return operator()(*lhs, *rhs);
00102 }
00103
00104 bool operator()(symbol_entry const & lhs,
00105 symbol_entry const & rhs) const;
00106
00107 protected:
00108 vector<sort_options::sort_order> const & compare_order;
00109 bool reverse_sort;
00110 };
00111
00112
00113 bool symbol_compare::operator()(symbol_entry const & lhs,
00114 symbol_entry const & rhs) const
00115 {
00116 for (size_t i = 0; i < compare_order.size(); ++i) {
00117 int ret = compare_by(compare_order[i], lhs, rhs);
00118
00119 if (reverse_sort)
00120 ret = -ret;
00121 if (ret != 0)
00122 return ret < 0;
00123 }
00124 return false;
00125 }
00126
00127
00128 }
00129
00130
00131 void sort_options::
00132 sort(symbol_collection & syms, bool reverse_sort, bool lf) const
00133 {
00134 long_filenames = lf;
00135
00136 vector<sort_order> sort_option(options);
00137 for (sort_order cur = first; cur != last; cur = sort_order(cur + 1)) {
00138 if (find(sort_option.begin(), sort_option.end(), cur) ==
00139 sort_option.end())
00140 sort_option.push_back(cur);
00141 }
00142
00143 stable_sort(syms.begin(), syms.end(),
00144 symbol_compare(sort_option, reverse_sort));
00145 }
00146
00147
00148 void sort_options::
00149 sort(diff_collection & syms, bool reverse_sort, bool lf) const
00150 {
00151 long_filenames = lf;
00152
00153 vector<sort_order> sort_option(options);
00154 for (sort_order cur = first; cur != last; cur = sort_order(cur + 1)) {
00155 if (find(sort_option.begin(), sort_option.end(), cur) ==
00156 sort_option.end())
00157 sort_option.push_back(cur);
00158 }
00159
00160 stable_sort(syms.begin(), syms.end(),
00161 symbol_compare(sort_option, reverse_sort));
00162 }
00163
00164
00165 void sort_options::add_sort_option(string const & name)
00166 {
00167 if (name == "vma") {
00168 options.push_back(vma);
00169 } else if (name == "sample") {
00170 options.push_back(sample);
00171 } else if (name == "symbol") {
00172 options.push_back(symbol);
00173 } else if (name == "debug") {
00174 options.push_back(debug);
00175 } else if (name == "image") {
00176 options.push_back(image);
00177 } else if (name == "app-name") {
00178 options.push_back(app_name);
00179 } else {
00180 ostringstream os;
00181 os << "unknown sort option: " << name << endl;
00182 throw op_fatal_error(os.str());
00183 }
00184 }
00185
00186
00187 void sort_options::add_sort_option(sort_options::sort_order order)
00188 {
00189 options.push_back(order);
00190 }