//===- Support/FileUtilities.cpp - File System Utilities ------------------===//
// 
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
// 
//===----------------------------------------------------------------------===//
//
// This file implements a family of utility functions which are useful for doing
// various things with files.
//
//===----------------------------------------------------------------------===//

#include "llvm/Support/FileUtilities.h"
#include "llvm/System/Path.h"
#include "llvm/System/MappedFile.h"
#include "llvm/ADT/StringExtras.h"
#include <cmath>
#include <cstring>
#include <cctype>
using namespace llvm;

static bool isNumberChar(char C) {
  switch (C) {
  case '0': case '1': case '2': case '3': case '4':
  case '5': case '6': case '7': case '8': case '9': 
  case '.': case '+': case '-':
  case 'e':
  case 'E': return true;
  default: return false;
  }
}

static char *BackupNumber(char *Pos, char *FirstChar) {
  // If we didn't stop in the middle of a number, don't backup.
  if (!isNumberChar(*Pos)) return Pos;

  // Otherwise, return to the start of the number.
  while (Pos > FirstChar && isNumberChar(Pos[-1]))
    --Pos;
  return Pos;
}

/// CompareNumbers - compare two numbers, returning true if they are different.
static bool CompareNumbers(char *&F1P, char *&F2P, char *F1End, char *F2End,
                           double AbsTolerance, double RelTolerance,
                           std::string *ErrorMsg) {
  char *F1NumEnd, *F2NumEnd;
  double V1 = 0.0, V2 = 0.0; 

  // 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;

  // If we stop on numbers, compare their difference.
  if (isNumberChar(*F1P) && isNumberChar(*F2P)) {
    V1 = strtod(F1P, &F1NumEnd);
    V2 = strtod(F2P, &F2NumEnd);
  } else {
    // Otherwise, the diff failed.
    F1NumEnd = F1P;
    F2NumEnd = F2P;
  }

  if (F1NumEnd == F1P || F2NumEnd == F2P) {
    if (ErrorMsg) *ErrorMsg = "Comparison failed, not a numeric difference.";
    return true;
  }

  // Check to see if these are inside the absolute tolerance
  if (AbsTolerance < std::abs(V1-V2)) {
    // Nope, check the relative tolerance...
    double Diff;
    if (V2)
      Diff = std::abs(V1/V2 - 1.0);
    else if (V1)
      Diff = std::abs(V2/V1 - 1.0);
    else
      Diff = 0;  // Both zero.
    if (Diff > RelTolerance) {
      if (ErrorMsg) {
        *ErrorMsg = "Compared: " + ftostr(V1) + " and " + ftostr(V2) +
                    ": diff = " + ftostr(Diff) + "\n";
        *ErrorMsg += "Out of tolerance: rel/abs: " + ftostr(RelTolerance) +
                     "/" + ftostr(AbsTolerance);
      }
      return true;
    }
  }

  // Otherwise, advance our read pointers to the end of the numbers.
  F1P = F1NumEnd;  F2P = F2NumEnd;
  return false;
}

// PadFileIfNeeded - If the files are not identical, we will have to be doing
// numeric comparisons in here.  There are bad cases involved where we (i.e.,
// strtod) might run off the beginning or end of the file if it starts or ends
// with a number.  Because of this, if needed, we pad the file so that it starts
// and ends with a null character.
static void PadFileIfNeeded(char *&FileStart, char *&FileEnd, char *&FP) {
  if (FileStart-FileEnd < 2 ||
      isNumberChar(FileStart[0]) || isNumberChar(FileEnd[-1])) {
    unsigned FileLen = FileEnd-FileStart;
    char *NewFile = new char[FileLen+2];
    NewFile[0] = 0;              // Add null padding
    NewFile[FileLen+1] = 0;      // Add null padding
    memcpy(NewFile+1, FileStart, FileLen);
    FP = NewFile+(FP-FileStart)+1;
    FileStart = NewFile+1;
    FileEnd = FileStart+FileLen;
  }
}

/// DiffFilesWithTolerance - Compare the two files specified, returning 0 if the
/// files match, 1 if they are different, and 2 if there is a file error.  This
/// function differs from DiffFiles in that you can specify an absolete and
/// relative FP error that is allowed to exist.  If you specify a string to fill
/// in for the error option, it will set the string to an error message if an
/// error occurs, allowing the caller to distinguish between a failed diff and a
/// file system error.
///
int llvm::DiffFilesWithTolerance(const sys::Path &FileA,
                                 const sys::Path &FileB,
                                 double AbsTol, double RelTol,
                                 std::string *Error) {
  try {
    // Check for zero length files because some systems croak when you try to
    // mmap an empty file.
    size_t A_size = FileA.getSize();
    size_t B_size = FileB.getSize();

    // If they are both zero sized then they're the same
    if (A_size == 0 && B_size == 0)
      return 0;
    // If only one of them is zero sized then they can't be the same
    if ((A_size == 0 || B_size == 0))
      return 1;

    // Now its safe to mmap the files into memory becasue both files
    // have a non-zero size. 
    sys::MappedFile F1(FileA);
    sys::MappedFile F2(FileB);
    F1.map();
    F2.map();

    // Okay, now that we opened the files, scan them for the first difference.
    char *File1Start = F1.charBase();
    char *File2Start = F2.charBase();
    char *File1End = File1Start+A_size;
    char *File2End = File2Start+B_size;
    char *F1P = File1Start;
    char *F2P = File2Start;

    if (A_size == B_size) {
      // Are the buffers identical?
      if (std::memcmp(File1Start, File2Start, A_size) == 0)
        return 0;

      if (AbsTol == 0 && RelTol == 0)
        return 1;   // Files different!
    }

    char *OrigFile1Start = File1Start;
    char *OrigFile2Start = File2Start;

    // If the files need padding, do so now.
    PadFileIfNeeded(File1Start, File1End, F1P);
    PadFileIfNeeded(File2Start, File2End, F2P);
    
    bool CompareFailed = false;
    while (1) {
      // Scan for the end of file or next difference.
      while (F1P < File1End && F2P < File2End && *F1P == *F2P)
        ++F1P, ++F2P;

      if (F1P >= File1End || F2P >= File2End) break;

      // 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);

      // Now that we are at the start of the numbers, compare them, exiting if
      // they don't match.
      if (CompareNumbers(F1P, F2P, File1End, File2End, AbsTol, RelTol, Error)) {
        CompareFailed = true;
        break;
      }
    }

    // Okay, we reached the end of file.  If both files are at the end, we
    // succeeded.
    bool F1AtEnd = F1P >= File1End;
    bool F2AtEnd = F2P >= File2End;
    if (!CompareFailed && (!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);

      // Now that we are at the start of the numbers, compare them, exiting if
      // they don't match.
      if (CompareNumbers(F1P, F2P, File1End, File2End, AbsTol, RelTol, Error))
        CompareFailed = true;

      // If we found the end, we succeeded.
      if (F1P < File1End || F2P < File2End)
        CompareFailed = true;
    }

    if (OrigFile1Start != File1Start)
      delete[] (File1Start-1);   // Back up past null byte
    if (OrigFile2Start != File2Start)
      delete[] (File2Start-1);   // Back up past null byte
    return CompareFailed;
  } catch (const std::string &Msg) {
    if (Error) *Error = Msg;
    return 2;
  }
}
