| 103 | |
| 104 | |
| 105 | void DumpStats() |
| 106 | { |
| 107 | FILE *out = 0; |
| 108 | if (mDumpFile.length > 0) |
| 109 | { |
| 110 | out = fopen(mDumpFile.c_str(), "wb"); |
| 111 | if (!out) |
| 112 | { |
| 113 | return; |
| 114 | } |
| 115 | } |
| 116 | |
| 117 | std::vector<ResultsEntry> results; |
| 118 | |
| 119 | results.reserve(mProfileStats.size()); |
| 120 | |
| 121 | int total = 0; |
| 122 | std::map<const char *, ProfileEntry>::iterator iter = |
| 123 | mProfileStats.begin(); |
| 124 | while (iter != mProfileStats.end()) { |
| 125 | ProfileEntry &pe = iter->second; |
| 126 | ResultsEntry re; |
| 127 | re.fullName = iter->first; |
| 128 | re.self = pe.self; |
| 129 | re.total = pe.total; |
| 130 | re.childrenPlusSelf = re.self; |
| 131 | ChildEntry internal; |
| 132 | internal.fullName = "(internal)"; |
| 133 | internal.self = re.self; |
| 134 | std::map<const char *, int>::iterator childIter = |
| 135 | pe.children.begin(); |
| 136 | int childTotal = 0; |
| 137 | while (childIter != pe.children.end()) { |
| 138 | ChildEntry ce; |
| 139 | ce.fullName = childIter->first; |
| 140 | ce.self = childIter->second; |
| 141 | re.childrenPlusSelf += ce.self; |
| 142 | re.children.push_back(ce); |
| 143 | childIter++; |
| 144 | } |
| 145 | re.children.push_back(internal); |
| 146 | std::sort(re.children.begin(), re.children.end()); |
| 147 | results.push_back(re); |
| 148 | total += re.self; |
| 149 | iter++; |
| 150 | } |
| 151 | |
| 152 | std::sort(results.begin(), results.end()); |
| 153 | |
| 154 | double scale = total ? (100.0 / total) : 1.0; |
| 155 | |
| 156 | int size = results.size(); |
| 157 | |
| 158 | for (int i = 0; i < size; i++) { |
| 159 | ResultsEntry &re = results[i]; |
| 160 | PROFILE_PRINT("%s %.2f%%/%.2f%%\n", re.fullName, re.total * scale, |
| 161 | re.self * scale); |
| 162 | if (re.children.size() == 1) { |
no test coverage detected