You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
168 lines
4.2 KiB
168 lines
4.2 KiB
/* |
|
* Copyright (C) 2015, The Android Open Source Project |
|
* |
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
* you may not use this file except in compliance with the License. |
|
* You may obtain a copy of the License at |
|
* |
|
* http://www.apache.org/licenses/LICENSE-2.0 |
|
* |
|
* Unless required by applicable law or agreed to in writing, software |
|
* distributed under the License is distributed on an "AS IS" BASIS, |
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
* See the License for the specific language governing permissions and |
|
* limitations under the License. |
|
*/ |
|
|
|
#include <algorithm> |
|
#include <iostream> |
|
#include <iterator> |
|
|
|
#include <android-base/strings.h> |
|
|
|
#include "os.h" |
|
#include "tests/test_util.h" |
|
|
|
using android::base::Split; |
|
using android::base::Join; |
|
using std::string; |
|
using std::vector; |
|
using std::cout; |
|
using std::endl; |
|
using std::distance; |
|
|
|
namespace android { |
|
namespace aidl { |
|
namespace test { |
|
|
|
string CanonicalNameToPath(const char* package_class, const char* extension) { |
|
string rel_path{package_class}; |
|
for (char& c : rel_path) { |
|
if (c == '.') { |
|
c = OS_PATH_SEPARATOR; |
|
} |
|
} |
|
rel_path += extension; |
|
return rel_path; |
|
} |
|
|
|
void SplitPackageClass(const string& package_class, |
|
string* rel_path, |
|
string* package, |
|
string* class_name) { |
|
*package = string{package_class, 0, package_class.rfind('.')}; |
|
*class_name = string{package_class, package_class.rfind('.') + 1}; |
|
*rel_path = CanonicalNameToPath(package_class.c_str(), ".aidl"); |
|
} |
|
|
|
void PrintDiff(const string& a, const string& b) { |
|
const int LEFT = 1; |
|
const int UP = 2; |
|
const int UP_LEFT = 4; |
|
|
|
auto a_lines = Split(a, "\n"); |
|
auto b_lines = Split(b, "\n"); |
|
|
|
struct diff_table_entry { |
|
size_t longest_common_subsequence_length; |
|
int propagation_directions; |
|
}; |
|
|
|
diff_table_entry table[a_lines.size() + 1][b_lines.size() + 1]; |
|
|
|
for (size_t i = 0; i < a_lines.size() + 1; ++i) { |
|
for (size_t j = 0; j < b_lines.size() + 1; ++j) { |
|
if (i == 0 || j == 0) { |
|
int directions = 0; |
|
|
|
if (i) { |
|
directions |= UP; |
|
} |
|
|
|
if (j) { |
|
directions |= LEFT; |
|
} |
|
|
|
table[i][j].longest_common_subsequence_length = 0; |
|
table[i][j].propagation_directions = directions; |
|
} else if (a_lines[i-1] == b_lines[j-1]) { |
|
table[i][j].longest_common_subsequence_length = |
|
table[i-1][j-1].longest_common_subsequence_length + 1; |
|
table[i][j].propagation_directions = UP_LEFT; |
|
} else { |
|
size_t length_up = table[i-1][j].longest_common_subsequence_length; |
|
size_t length_left = table[i][j-1].longest_common_subsequence_length; |
|
int directions = 0; |
|
size_t length; |
|
|
|
if (length_up >= length_left) { |
|
directions |= UP; |
|
length = length_up; |
|
} |
|
|
|
if (length_left >= length_up) { |
|
directions |= LEFT; |
|
length = length_left; |
|
} |
|
|
|
table[i][j].longest_common_subsequence_length = length; |
|
table[i][j].propagation_directions = directions; |
|
} |
|
} |
|
} |
|
|
|
size_t i = a_lines.size(); |
|
size_t j = b_lines.size(); |
|
vector<string> output; |
|
|
|
while (table[i][j].propagation_directions) { |
|
if (table[i][j].propagation_directions & UP_LEFT) { |
|
output.push_back(" " + a_lines[i-1]); |
|
i--; |
|
j--; |
|
} else if (table[i][j].propagation_directions & UP) { |
|
output.push_back("-" + a_lines[i-1]); |
|
i--; |
|
} else { |
|
output.push_back("+" + b_lines[j-1]); |
|
j--; |
|
} |
|
} |
|
|
|
int print_mask = 0; |
|
bool printed_last = false; |
|
size_t line_number = 0; |
|
|
|
for (auto it = output.crbegin(), frontier = output.crbegin(); |
|
it != output.crend(); ++it) { |
|
while (frontier != output.crend() && distance(it, frontier) <= 3) { |
|
print_mask <<= 1; |
|
print_mask &= 0x7f; |
|
|
|
if ((*frontier)[0] != ' ') { |
|
print_mask |= 1; |
|
} |
|
|
|
frontier++; |
|
} |
|
|
|
if ((*it)[0] != '-') { |
|
line_number++; |
|
} |
|
|
|
if (print_mask) { |
|
if (!printed_last) { |
|
cout << "Line: " << line_number << endl; |
|
} |
|
|
|
cout << *it << endl; |
|
printed_last = true; |
|
} else { |
|
printed_last = false; |
|
} |
|
} |
|
} |
|
|
|
} // namespace test |
|
} // namespace android |
|
} // namespace aidl
|
|
|