Index: tools/fpcmp.c =================================================================== --- tools/fpcmp.c +++ tools/fpcmp.c @@ -53,7 +53,8 @@ return isDigitChar(C) || isSignedChar(C) || C == '.'; } -static const char *AdvanceNumber(const char *StartPos, const char *End) { +static const char *AdvanceNumber(const char *StartPos, const char *End, + bool NeedsPostDecimalDigit) { const char *Pos = StartPos; const char *EndOfNumber = NULL; @@ -70,8 +71,9 @@ // Decimal separator if (Pos < End && *Pos == '.') { ++Pos; + EndOfNumber = Pos; - // Post-decimal digits (require at least one when period present) + // Post-decimal digits bool HasPostDecimalDigit = false; while (Pos < End && isDigitChar(*Pos)) { HasPostDecimalDigit = true; @@ -79,7 +81,10 @@ ++Pos; EndOfNumber = Pos; } - if (!HasPostDecimalDigit) + + // Sometimes we require at least one decimal digit when the decimal point is + // present. + if (NeedsPostDecimalDigit && !HasPostDecimalDigit) return EndOfNumber; } @@ -250,8 +255,8 @@ int diff_files_with_tolerance(const char *path_a, const char *path_b, double absolute_tolerance, - double relative_tolerance, - bool ignore_whitespace) { + double relative_tolerance, bool ignore_whitespace, + bool post_decimal_digit) { /* First, load the file buffers completely into memory. */ long A_size, B_size; char *data_a = load_file(path_a, &A_size); @@ -303,8 +308,10 @@ skip_whitespace(&F2NumStart, File2End); } - const char *F1NumEnd = AdvanceNumber(F1NumStart, File1End); - const char *F2NumEnd = AdvanceNumber(F2NumStart, File2End); + const char *F1NumEnd = + AdvanceNumber(F1NumStart, File1End, post_decimal_digit); + const char *F2NumEnd = + AdvanceNumber(F2NumStart, File2End, post_decimal_digit); // If one side is a number, but not the other, we found a difference. if (!F1NumEnd || !F2NumEnd) { @@ -369,12 +376,15 @@ } void usage() { - fprintf(stderr, "usage: %s [-a VALUE] [-r VALUE] [-i] \n\n", + fprintf(stderr, + "usage: %s [-a VALUE] [-r VALUE] [-i] [-d] \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"); + fprintf(stderr, + "The -d switch requires at least one digit after a decimal point\n"); exit(2); } @@ -382,6 +392,7 @@ double relative_tolerance = 0.0; double absolute_tolerance = 0.0; bool ignore_whitespace = false; + bool post_decimal_digit = false; int i; g_program = argv[0]; @@ -420,6 +431,10 @@ ignore_whitespace = true; break; + case 'd': + post_decimal_digit = true; + break; + default: fprintf(stderr, "error: invalid argument '%s'\n\n", arg); usage(); @@ -432,5 +447,6 @@ } return diff_files_with_tolerance(argv[i], argv[i + 1], absolute_tolerance, - relative_tolerance, ignore_whitespace); + relative_tolerance, ignore_whitespace, + post_decimal_digit); }