aboutsummaryrefslogtreecommitdiffhomepage
path: root/tools/skdiff_main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/skdiff_main.cpp')
-rw-r--r--tools/skdiff_main.cpp126
1 files changed, 103 insertions, 23 deletions
diff --git a/tools/skdiff_main.cpp b/tools/skdiff_main.cpp
index 9c327dfab6..61fd83bbb0 100644
--- a/tools/skdiff_main.cpp
+++ b/tools/skdiff_main.cpp
@@ -26,7 +26,7 @@
* third directory for each pair.
* Creates an index.html in the current third directory to compare each
* pair that does not match exactly.
- * Does *not* recursively descend directories.
+ * Recursively descends directories, unless run with --norecurse.
*
* Returns zero exit code if all images match across baseDir and comparisonDir.
*/
@@ -612,6 +612,27 @@ static void compute_diff(DiffRecord* dr,
dr->fAverageMismatchB = ((float) totalMismatchB) / pixelCount;
}
+/// Return a copy of the "input" string, within which we have replaced all instances
+/// of oldSubstring with newSubstring.
+///
+/// TODO: If we like this, we should move it into the core SkString implementation,
+/// adding more checks and ample test cases, and paying more attention to efficiency.
+static SkString replace_all(const SkString &input,
+ const char oldSubstring[], const char newSubstring[]) {
+ SkString output;
+ const char *input_cstr = input.c_str();
+ const char *first_char = input_cstr;
+ const char *match_char;
+ int oldSubstringLen = strlen(oldSubstring);
+ while (NULL != (match_char = strstr(first_char, oldSubstring))) {
+ output.append(first_char, (match_char - first_char));
+ output.append(newSubstring);
+ first_char = match_char + oldSubstringLen;
+ }
+ output.append(first_char);
+ return output;
+}
+
static SkString filename_to_derived_filename (const SkString& filename,
const char *suffix) {
SkString diffName (filename);
@@ -619,6 +640,10 @@ static SkString filename_to_derived_filename (const SkString& filename,
int dotOffset = strrchr(cstring, '.') - cstring;
diffName.remove(dotOffset, diffName.size() - dotOffset);
diffName.append(suffix);
+
+ // In case we recursed into subdirectories, replace slashes with something else
+ // so the diffs will all be written into a single flat directory.
+ diffName = replace_all(diffName, PATH_DIV_STR, "_");
return diffName;
}
@@ -686,22 +711,70 @@ static bool string_contains_any_of(const SkString& string,
return false;
}
-/// Iterate over dir and get all files that:
-/// - match any of the substrings in matchSubstrings, but...
-/// - DO NOT match any of the substrings in nomatchSubstrings
-/// Returns the list of files in *files.
+/// Internal (potentially recursive) implementation of get_file_list.
+static void get_file_list_subdir(const SkString& rootDir, const SkString& subDir,
+ const StringArray& matchSubstrings,
+ const StringArray& nomatchSubstrings,
+ bool recurseIntoSubdirs, FileArray *files) {
+ bool isSubDirEmpty = subDir.isEmpty();
+ SkString dir(rootDir);
+ if (!isSubDirEmpty) {
+ dir.append(PATH_DIV_STR);
+ dir.append(subDir);
+ }
+
+ // Iterate over files (not directories) within dir.
+ SkOSFile::Iter fileIterator(dir.c_str());
+ SkString fileName;
+ while (fileIterator.next(&fileName, false)) {
+ if (fileName.startsWith(".")) {
+ continue;
+ }
+ SkString pathRelativeToRootDir(subDir);
+ if (!isSubDirEmpty) {
+ pathRelativeToRootDir.append(PATH_DIV_STR);
+ }
+ pathRelativeToRootDir.append(fileName);
+ if (string_contains_any_of(pathRelativeToRootDir, matchSubstrings) &&
+ !string_contains_any_of(pathRelativeToRootDir, nomatchSubstrings)) {
+ files->push(new SkString(pathRelativeToRootDir));
+ }
+ }
+
+ // Recurse into any non-ignored subdirectories.
+ if (recurseIntoSubdirs) {
+ SkOSFile::Iter dirIterator(dir.c_str());
+ SkString dirName;
+ while (dirIterator.next(&dirName, true)) {
+ if (dirName.startsWith(".")) {
+ continue;
+ }
+ SkString pathRelativeToRootDir(subDir);
+ if (!isSubDirEmpty) {
+ pathRelativeToRootDir.append(PATH_DIV_STR);
+ }
+ pathRelativeToRootDir.append(dirName);
+ if (!string_contains_any_of(pathRelativeToRootDir, nomatchSubstrings)) {
+ get_file_list_subdir(rootDir, pathRelativeToRootDir,
+ matchSubstrings, nomatchSubstrings, recurseIntoSubdirs,
+ files);
+ }
+ }
+ }
+}
+
+/// Iterate over dir and get all files whose filename:
+/// - matches any of the substrings in matchSubstrings, but...
+/// - DOES NOT match any of the substrings in nomatchSubstrings
+/// - DOES NOT start with a dot (.)
+/// Adds the matching files to the list in *files.
static void get_file_list(const SkString& dir,
const StringArray& matchSubstrings,
const StringArray& nomatchSubstrings,
- FileArray *files) {
- SkOSFile::Iter it(dir.c_str());
- SkString filename;
- while (it.next(&filename)) {
- if (string_contains_any_of(filename, matchSubstrings) &&
- !string_contains_any_of(filename, nomatchSubstrings)) {
- files->push(new SkString(filename));
- }
- }
+ bool recurseIntoSubdirs, FileArray *files) {
+ get_file_list_subdir(dir, SkString(""),
+ matchSubstrings, nomatchSubstrings, recurseIntoSubdirs,
+ files);
}
static void release_file_list(FileArray *files) {
@@ -723,6 +796,7 @@ static void create_diff_images (DiffMetricProc dmp,
const SkString& outputDir,
const StringArray& matchSubstrings,
const StringArray& nomatchSubstrings,
+ bool recurseIntoSubdirs,
DiffSummary* summary) {
SkASSERT(!baseDir.isEmpty());
SkASSERT(!comparisonDir.isEmpty());
@@ -730,8 +804,8 @@ static void create_diff_images (DiffMetricProc dmp,
FileArray baseFiles;
FileArray comparisonFiles;
- get_file_list(baseDir, matchSubstrings, nomatchSubstrings, &baseFiles);
- get_file_list(comparisonDir, matchSubstrings, nomatchSubstrings,
+ get_file_list(baseDir, matchSubstrings, nomatchSubstrings, recurseIntoSubdirs, &baseFiles);
+ get_file_list(comparisonDir, matchSubstrings, nomatchSubstrings, recurseIntoSubdirs,
&comparisonFiles);
if (!baseFiles.isEmpty()) {
@@ -1146,6 +1220,7 @@ static void usage (char * argv0) {
"\n filenames contain this substring."
"\n this flag may be repeated."
"\n --noprintdirs: do not print the directories used."
+"\n --norecurse: do not recurse into subdirectories."
"\n --sortbymaxmismatch: sort by worst color channel mismatch;"
"\n break ties with -sortbymismatch"
"\n --sortbymismatch: sort by average color channel mismatch"
@@ -1180,7 +1255,8 @@ int main (int argc, char ** argv) {
bool generateDiffs = true;
bool listFilenames = false;
- bool printDirs = true;
+ bool printDirNames = true;
+ bool recurseIntoSubdirs = true;
RecordArray differences;
DiffSummary summary;
@@ -1219,7 +1295,11 @@ int main (int argc, char ** argv) {
continue;
}
if (!strcmp(argv[i], "--noprintdirs")) {
- printDirs = false;
+ printDirNames = false;
+ continue;
+ }
+ if (!strcmp(argv[i], "--norecurse")) {
+ recurseIntoSubdirs = false;
continue;
}
if (!strcmp(argv[i], "--sortbymaxmismatch")) {
@@ -1271,14 +1351,14 @@ int main (int argc, char ** argv) {
if (!baseDir.endsWith(PATH_DIV_STR)) {
baseDir.append(PATH_DIV_STR);
}
- if (printDirs) {
+ if (printDirNames) {
printf("baseDir is [%s]\n", baseDir.c_str());
}
if (!comparisonDir.endsWith(PATH_DIV_STR)) {
comparisonDir.append(PATH_DIV_STR);
}
- if (printDirs) {
+ if (printDirNames) {
printf("comparisonDir is [%s]\n", comparisonDir.c_str());
}
@@ -1286,11 +1366,11 @@ int main (int argc, char ** argv) {
outputDir.append(PATH_DIV_STR);
}
if (generateDiffs) {
- if (printDirs) {
+ if (printDirNames) {
printf("writing diffs to outputDir is [%s]\n", outputDir.c_str());
}
} else {
- if (printDirs) {
+ if (printDirNames) {
printf("not writing any diffs to outputDir [%s]\n", outputDir.c_str());
}
outputDir.set("");
@@ -1304,7 +1384,7 @@ int main (int argc, char ** argv) {
create_diff_images(diffProc, colorThreshold, &differences,
baseDir, comparisonDir, outputDir,
- matchSubstrings, nomatchSubstrings, &summary);
+ matchSubstrings, nomatchSubstrings, recurseIntoSubdirs, &summary);
summary.print(listFilenames, failOnResultType);
if (differences.count()) {