[test-suite] r311385 - fpmc: Add -i option to ignore whitespace changes.

Michael Kruse via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 21 14:19:46 PDT 2017


Author: meinersbur
Date: Mon Aug 21 14:19:46 2017
New Revision: 311385

URL: http://llvm.org/viewvc/llvm-project?rev=311385&view=rev
Log:
fpmc: Add -i option to ignore whitespace changes.

Add a switch '-i' to fpcmp that allows ignoring whitespace changes.
This is required for SPEC CPU 2017 511.povray_r which has its reference
output stored with CRLF line endings, but the actual output on UNIX
system has LF line endings. Also, 519.lbm_r/619.lbm_s mixes indention
by tabs and spaces in its reference output.

This also fixes an infinite loop when comparing a number followed by
unequal non-number character, such as "5a" and "5b", and some
out-of-ranges of the file buffers.

Differential Revision: https://reviews.llvm.org/D36768

Modified:
    test-suite/trunk/tools/fpcmp.c

Modified: test-suite/trunk/tools/fpcmp.c
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/tools/fpcmp.c?rev=311385&r1=311384&r2=311385&view=diff
==============================================================================
--- test-suite/trunk/tools/fpcmp.c (original)
+++ test-suite/trunk/tools/fpcmp.c Mon Aug 21 14:19:46 2017
@@ -47,13 +47,23 @@ static bool isNumberChar(char C) {
   }
 }
 
-static const char *BackupNumber(const char *Pos, const char *FirstChar) {
+static const char *BackupNumber(const char *Pos, const char *FirstChar,
+                                const char *End) {
+  // If already at the very beginning, we cannot go back further.
+  // It ensures that the access Pos[-1] is valid.
+  // This also handles the case where the file is empty (FirstChar == End).
+  if (Pos == FirstChar)
+    return Pos;
+
   // If we didn't stop in the middle of a number, don't backup.
-  if (!isNumberChar(*Pos) && !isNumberChar(Pos[-1])) return Pos;
+  if (!(Pos == End || isNumberChar(*Pos)) && !isNumberChar(Pos[-1]))
+    return Pos;
+
   // If we're one past the number, the two numbers can have different number
   // of digits. Even if we're wrong, and we get the previous number, the
   // comparison should have failed anyway.
-  if (!isNumberChar(*Pos)) Pos--;
+  if (Pos == End || !isNumberChar(*Pos))
+    Pos--;
 
   // Otherwise, return to the start of the number.
   bool HasPeriod = false;
@@ -81,6 +91,15 @@ static const char *EndOfNumber(const cha
   return Pos;
 }
 
+static bool skip_whitespace(const char **FP, const char *FEnd) {
+  bool skipped_some = false;
+  while (*FP < FEnd && isspace((unsigned char)**FP)) {
+    skipped_some = true;
+    ++*FP;
+  }
+  return skipped_some;
+}
+
 /// CompareNumbers - compare two numbers, returning true if they are different.
 static bool CompareNumbers(const char **F1PP, const char **F2PP,
                            const char *F1End, const char *F2End,
@@ -92,10 +111,14 @@ static bool CompareNumbers(const char **
 
   // If one of the positions is at a space and the other isn't, chomp up 'til
   // the end of the space.
-  while (isspace(*F1P) && F1P != F1End)
-    ++F1P;
-  while (isspace(*F2P) && F2P != F2End)
-    ++F2P;
+  skip_whitespace(&F1P, F1End);
+  skip_whitespace(&F2P, F2End);
+
+  if (F1P == F1End || F2P == F2End) {
+    fprintf(stderr, ("%s: FP Comparison failed, reached end of file\n"),
+            g_program);
+    return true;
+  }
 
   // If we stop on numbers, compare their difference.
   if (!isNumberChar(*F1P) || !isNumberChar(*F2P)) {
@@ -217,7 +240,8 @@ char *load_file(const char *path, long *
 
 int diff_files_with_tolerance(const char *path_a, const char *path_b,
                               double absolute_tolerance,
-                              double relative_tolerance) {
+                              double relative_tolerance,
+                              bool ignore_whitespace) {
   /* First, load the file buffers completely into memory. */
   long A_size, B_size;
   char *data_a = load_file(path_a, &A_size);
@@ -228,7 +252,8 @@ int diff_files_with_tolerance(const char
     return 0;
 
   /* Otherwise, if our tolerances are 0 then we are done. */
-  if (relative_tolerance == 0.0 && absolute_tolerance == 0.0) {
+  if (relative_tolerance == 0.0 && absolute_tolerance == 0.0 &&
+      !ignore_whitespace) {
     fprintf(stderr, "%s: files differ without tolerance allowance\n",
             g_program);
     return 1;
@@ -246,16 +271,42 @@ int diff_files_with_tolerance(const char
 
   while (1) {
     // Scan for the end of file or next difference.
-    while (F1P < File1End && F2P < File2End && *F1P == *F2P)
-      ++F1P, ++F2P;
+    while (F1P < File1End && F2P < File2End) {
+      if (*F1P == *F2P) {
+        ++F1P, ++F2P;
+        continue;
+      }
+
+      // With whitespace ignored, skip whitespace chars (if any) and recheck for
+      // the next difference.
+      if (ignore_whitespace) {
+        if (skip_whitespace(&F1P, File1End) | skip_whitespace(&F2P, File2End))
+          continue;
+      }
+
+      break;
+    }
 
     if (F1P >= File1End || F2P >= File2End) break;
 
+    // BackupNumber will also backup when at the first char after a number. This
+    // is to catch when one of the number has more trailing floating-point zeros
+    // than the other. However, when this is the case in both buffers, we'd
+    // repeat the most recent number forever.
+    // Therefore, we fast-stop if both buffers have no number at the current
+    // position.
+    if (!isNumberChar(*F1P) && !isNumberChar(*F2P)) {
+      fprintf(stderr, "%s: FP Comparison failed, not a numeric difference "
+                      "between '%c' and '%c'\n",
+              g_program, F1P[0], F2P[0]);
+      return 1;
+    }
+
     // Okay, we must have found a difference.  Backup to the start of the
     // current number each stream is at so that we can compare from the
     // beginning.
-    F1P = BackupNumber(F1P, File1Start);
-    F2P = BackupNumber(F2P, File2Start);
+    F1P = BackupNumber(F1P, File1Start, File1End);
+    F2P = BackupNumber(F2P, File2Start, File2End);
 
     // Now that we are at the start of the numbers, compare them, exiting if
     // they don't match.
@@ -264,10 +315,10 @@ int diff_files_with_tolerance(const char
       return 1;
   }
 
-  // Avoid reading before byte 0 in the loop below.
-  if (A_size == 0 || B_size == 0) {
-    fprintf(stderr, "%s File sizes differ\n", g_program);
-    return 1;
+  // Skip any whitespace at the end of the file.
+  if (ignore_whitespace) {
+    skip_whitespace(&F1P, File1End);
+    skip_whitespace(&F2P, File2End);
   }
 
   // Okay, we reached the end of file.  If both files are at the end, we
@@ -276,10 +327,8 @@ int diff_files_with_tolerance(const char
   bool F2AtEnd = F2P >= File2End;
   if (!F1AtEnd || !F2AtEnd) {
     // Else, we might have run off the end due to a number: backup and retry.
-    if (F1AtEnd && isNumberChar(F1P[-1])) --F1P;
-    if (F2AtEnd && isNumberChar(F2P[-1])) --F2P;
-    F1P = BackupNumber(F1P, File1Start);
-    F2P = BackupNumber(F2P, File2Start);
+    F1P = BackupNumber(F1P, File1Start, File1End);
+    F2P = BackupNumber(F2P, File2Start, File2End);
 
     // Now that we are at the start of the numbers, compare them, exiting if
     // they don't match.
@@ -287,6 +336,12 @@ int diff_files_with_tolerance(const char
                        absolute_tolerance, relative_tolerance))
       return 1;
 
+    // There might be more whitespace after the number.
+    if (ignore_whitespace) {
+      skip_whitespace(&F1P, File1End);
+      skip_whitespace(&F2P, File2End);
+    }
+
     // If we found the end, we succeeded.
     if (F1P < File1End || F2P < File2End)
       return 1;
@@ -296,17 +351,19 @@ int diff_files_with_tolerance(const char
 }
 
 void usage() {
-  fprintf(stderr, "usage: %s [-a VALUE] [-r VALUE] <path-A> <path-B>\n\n",
+  fprintf(stderr, "usage: %s [-a VALUE] [-r VALUE] [-i] <path-A> <path-B>\n\n",
           g_program);
   fprintf(stderr, "Compare two files using absolute and relative tolerances\n");
   fprintf(stderr, "when comparing differences between two character\n");
   fprintf(stderr, "which could be real numbers\n");
+  fprintf(stderr, "The -i switch ignores whitespace differences\n");
   exit(2);
 }
 
 int main(int argc, char * const argv[]) {
   double relative_tolerance = 0.0;
   double absolute_tolerance = 0.0;
+  bool ignore_whitespace = false;
   int i;
 
   g_program = argv[0];
@@ -341,6 +398,10 @@ int main(int argc, char * const argv[])
       }
       break;
 
+    case 'i':
+      ignore_whitespace = true;
+      break;
+
     default:
       fprintf(stderr, "error: invalid argument '%s'\n\n", arg);
       usage();
@@ -352,6 +413,6 @@ int main(int argc, char * const argv[])
     usage();
   }
 
-  return diff_files_with_tolerance(argv[i], argv[i + 1],
-                                   absolute_tolerance, relative_tolerance);
+  return diff_files_with_tolerance(argv[i], argv[i + 1], absolute_tolerance,
+                                   relative_tolerance, ignore_whitespace);
 }




More information about the llvm-commits mailing list