<commit_before>//===--- SourceManager.cpp - Track and cache source files -----------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by Chris Lattner and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file implements the SourceManager interface.
//
//===----------------------------------------------------------------------===//

#include "clang/Basic/SourceManager.h"
#include "clang/Basic/FileManager.h"
#include "llvm/Config/config.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/System/Path.h"
#include "llvm/Bitcode/Serialize.h"
#include "llvm/Bitcode/Deserialize.h"
#include <algorithm>
#include <iostream>
#include <fcntl.h>
using namespace clang;
using namespace SrcMgr;
using llvm::MemoryBuffer;

ContentCache::~ContentCache() {
  delete Buffer;
  delete [] SourceLineCache;
}

// FIXME: REMOVE THESE
#include <unistd.h>
#include <sys/types.h>
#if !defined(_MSC_VER) && !defined(__MINGW32__)
#include <sys/uio.h>
#include <sys/fcntl.h>
#else
#include <io.h>
#endif
#include <cerrno>

static const MemoryBuffer *ReadFileFast(const FileEntry *FileEnt) {
#if 0
  // FIXME: Reintroduce this and zap this function once the common llvm stuff
  // is fast for the small case.
  return MemoryBuffer::getFile(FileEnt->getName(), strlen(FileEnt->getName()),
                               FileEnt->getSize());
#endif

  // If the file is larger than some threshold, use 'read', otherwise use mmap.
  if (FileEnt->getSize() >= 4096*4)
    return MemoryBuffer::getFile(FileEnt->getName(), strlen(FileEnt->getName()),
                                 0, FileEnt->getSize());

  MemoryBuffer *SB = MemoryBuffer::getNewUninitMemBuffer(FileEnt->getSize(),
                                                         FileEnt->getName());
  char *BufPtr = const_cast<char*>(SB->getBufferStart());

#if defined(LLVM_ON_WIN32)
  int FD = ::open(FileEnt->getName(), O_RDONLY|O_BINARY);
#else
  int FD = ::open(FileEnt->getName(), O_RDONLY);
#endif
  if (FD == -1) {
    delete SB;
    return 0;
  }

  unsigned BytesLeft = FileEnt->getSize();
  while (BytesLeft) {
    ssize_t NumRead = ::read(FD, BufPtr, BytesLeft);
    if (NumRead != -1) {
      BytesLeft -= NumRead;
      BufPtr += NumRead;
    } else if (errno == EINTR) {
      // try again
    } else {
      // error reading.
      close(FD);
      delete SB;
      return 0;
    }
  }
  close(FD);

  return SB;
}

/// getFileInfo - Create or return a cached FileInfo for the specified file.
///
const ContentCache* SourceManager::getContentCache(const FileEntry *FileEnt) {

  assert(FileEnt && "Didn't specify a file entry to use?");
  // Do we already have information about this file?
  std::set<ContentCache>::iterator I =
    FileInfos.lower_bound(ContentCache(FileEnt));

  if (I != FileInfos.end() && I->Entry == FileEnt)
    return &*I;

  // Nope, get information.
  const MemoryBuffer *File = ReadFileFast(FileEnt);
  if (File == 0)
    return 0;

  ContentCache& Entry = const_cast<ContentCache&>(*FileInfos.insert(I,FileEnt));

  Entry.Buffer = File;
  Entry.SourceLineCache = 0;
  Entry.NumLines = 0;
  return &Entry;
}

/// createMemBufferInfoRec - Create a new ContentCache for the specified memory
/// buffer.  This does no caching.
const ContentCache*
SourceManager::createMemBufferContentCache(const MemoryBuffer *Buffer) {
  // Add a new ContentCache to the MemBufferInfos list and return it.  We
  // must default construct the object first that the instance actually
  // stored within MemBufferInfos actually owns the Buffer, and not any
  // temporary we would use in the call to "push_back".
  MemBufferInfos.push_back(ContentCache());
  ContentCache& Entry = const_cast<ContentCache&>(MemBufferInfos.back());
  Entry.Buffer = Buffer;
  return &Entry;
}

/// createFileID - Create a new fileID for the specified ContentCache and
/// include position.  This works regardless of whether the ContentCache
/// corresponds to a file or some other input source.
unsigned SourceManager::createFileID(const ContentCache *File,
                                     SourceLocation IncludePos) {
  // If FileEnt is really large (e.g. it's a large .i file), we may not be able
  // to fit an arbitrary position in the file in the FilePos field.  To handle
  // this, we create one FileID for each chunk of the file that fits in a
  // FilePos field.
  unsigned FileSize = File->Buffer->getBufferSize();
  if (FileSize+1 < (1 << SourceLocation::FilePosBits)) {
    FileIDs.push_back(FileIDInfo::get(IncludePos, 0, File));
    assert(FileIDs.size() < (1 << SourceLocation::FileIDBits) &&
           "Ran out of file ID's!");
    return FileIDs.size();
  }

  // Create one FileID for each chunk of the file.
  unsigned Result = FileIDs.size()+1;

  unsigned ChunkNo = 0;
  while (1) {
    FileIDs.push_back(FileIDInfo::get(IncludePos, ChunkNo++, File));

    if (FileSize+1 < (1 << SourceLocation::FilePosBits)) break;
    FileSize -= (1 << SourceLocation::FilePosBits);
  }

  assert(FileIDs.size() < (1 << SourceLocation::FileIDBits) &&
         "Ran out of file ID's!");
  return Result;
}

/// getInstantiationLoc - Return a new SourceLocation that encodes the fact
/// that a token from physloc PhysLoc should actually be referenced from
/// InstantiationLoc.
SourceLocation SourceManager::getInstantiationLoc(SourceLocation PhysLoc,
                                                  SourceLocation InstantLoc) {
  // The specified source location may be a mapped location, due to a macro
  // instantiation or #line directive.  Strip off this information to find out
  // where the characters are actually located.
  PhysLoc = getPhysicalLoc(PhysLoc);

  // Resolve InstantLoc down to a real logical location.
  InstantLoc = getLogicalLoc(InstantLoc);

  // If the last macro id is close to the currently requested location, try to
  // reuse it.  This implements a small cache.
  for (int i = MacroIDs.size()-1, e = MacroIDs.size()-6; i >= 0 && i != e; --i){
    MacroIDInfo &LastOne = MacroIDs[i];

    // The instanitation point and source physloc have to exactly match to reuse
    // (for now).  We could allow "nearby" instantiations in the future.
    if (LastOne.getInstantiationLoc() != InstantLoc ||
        LastOne.getPhysicalLoc().getFileID() != PhysLoc.getFileID())
      continue;

    // Check to see if the physloc of the token came from near enough to reuse.
    int PhysDelta = PhysLoc.getRawFilePos() -
                    LastOne.getPhysicalLoc().getRawFilePos();
    if (SourceLocation::isValidMacroPhysOffs(PhysDelta))
      return SourceLocation::getMacroLoc(i, PhysDelta, 0);
  }

  MacroIDs.push_back(MacroIDInfo::get(InstantLoc, PhysLoc));
  return SourceLocation::getMacroLoc(MacroIDs.size()-1, 0, 0);
}

/// getBufferData - Return a pointer to the start and end of the character
/// data for the specified FileID.
std::pair<const char*, const char*>
SourceManager::getBufferData(unsigned FileID) const {
  const llvm::MemoryBuffer *Buf = getBuffer(FileID);
  return std::make_pair(Buf->getBufferStart(), Buf->getBufferEnd());
}

/// getCharacterData - Return a pointer to the start of the specified location
/// in the appropriate MemoryBuffer.
const char *SourceManager::getCharacterData(SourceLocation SL) const {
  // Note that this is a hot function in the getSpelling() path, which is
  // heavily used by -E mode.
  SL = getPhysicalLoc(SL);

  return getContentCache(SL.getFileID())->Buffer->getBufferStart() +
         getFullFilePos(SL);
}

/// getColumnNumber - Return the column # for the specified file position.
/// this is significantly cheaper to compute than the line number.  This returns
/// zero if the column number isn't known.
unsigned SourceManager::getColumnNumber(SourceLocation Loc) const {
  unsigned FileID = Loc.getFileID();
  if (FileID == 0) return 0;

  unsigned FilePos = getFullFilePos(Loc);
  const MemoryBuffer *Buffer = getBuffer(FileID);
  const char *Buf = Buffer->getBufferStart();

  unsigned LineStart = FilePos;
  while (LineStart && Buf[LineStart-1] != '\n' && Buf[LineStart-1] != '\r')
    --LineStart;
  return FilePos-LineStart+1;
}

/// getSourceName - This method returns the name of the file or buffer that
/// the SourceLocation specifies.  This can be modified with #line directives,
/// etc.
const char *SourceManager::getSourceName(SourceLocation Loc) const {
  unsigned FileID = Loc.getFileID();
  if (FileID == 0) return "";
  return getContentCache(FileID)->Buffer->getBufferIdentifier();
}

static void ComputeLineNumbers(ContentCache* FI) DISABLE_INLINE;
static void ComputeLineNumbers(ContentCache* FI) {
  const MemoryBuffer *Buffer = FI->Buffer;

  // Find the file offsets of all of the *physical* source lines.  This does
  // not look at trigraphs, escaped newlines, or anything else tricky.
  std::vector<unsigned> LineOffsets;

  // Line #1 starts at char 0.
  LineOffsets.push_back(0);

  const unsigned char *Buf = (const unsigned char *)Buffer->getBufferStart();
  const unsigned char *End = (const unsigned char *)Buffer->getBufferEnd();
  unsigned Offs = 0;
  while (1) {
    // Skip over the contents of the line.
    // TODO: Vectorize this?  This is very performance sensitive for programs
    // with lots of diagnostics and in -E mode.
    const unsigned char *NextBuf = (const unsigned char *)Buf;
    while (*NextBuf != '\n' && *NextBuf != '\r' && *NextBuf != '\0')
      ++NextBuf;
    Offs += NextBuf-Buf;
    Buf = NextBuf;

    if (Buf[0] == '\n' || Buf[0] == '\r') {
      // If this is \n\r or \r\n, skip both characters.
      if ((Buf[1] == '\n' || Buf[1] == '\r') && Buf[0] != Buf[1])
        ++Offs, ++Buf;
      ++Offs, ++Buf;
      LineOffsets.push_back(Offs);
    } else {
      // Otherwise, this is a null.  If end of file, exit.
      if (Buf == End) break;
      // Otherwise, skip the null.
      ++Offs, ++Buf;
    }
  }
  LineOffsets.push_back(Offs);

  // Copy the offsets into the FileInfo structure.
  FI->NumLines = LineOffsets.size();
  FI->SourceLineCache = new unsigned[LineOffsets.size()];
  std::copy(LineOffsets.begin(), LineOffsets.end(), FI->SourceLineCache);
}

/// getLineNumber - Given a SourceLocation, return the physical line number
/// for the position indicated.  This requires building and caching a table of
/// line offsets for the MemoryBuffer, so this is not cheap: use only when
/// about to emit a diagnostic.
unsigned SourceManager::getLineNumber(SourceLocation Loc) {
  unsigned FileID = Loc.getFileID();
  if (FileID == 0) return 0;

  ContentCache* Content;

  if (LastLineNoFileIDQuery == FileID)
    Content = LastLineNoContentCache;
  else
    Content = const_cast<ContentCache*>(getContentCache(FileID));

  // If this is the first use of line information for this buffer, compute the
  /// SourceLineCache for it on demand.
  if (Content->SourceLineCache == 0)
    ComputeLineNumbers(Content);

  // Okay, we know we have a line number table.  Do a binary search to find the
  // line number that this character position lands on.
  unsigned *SourceLineCache = Content->SourceLineCache;
  unsigned *SourceLineCacheStart = SourceLineCache;
  unsigned *SourceLineCacheEnd = SourceLineCache + Content->NumLines;

  unsigned QueriedFilePos = getFullFilePos(Loc)+1;

  // If the previous query was to the same file, we know both the file pos from
  // that query and the line number returned.  This allows us to narrow the
  // search space from the entire file to something near the match.
  if (LastLineNoFileIDQuery == FileID) {
    if (QueriedFilePos >= LastLineNoFilePos) {
      SourceLineCache = SourceLineCache+LastLineNoResult-1;

      // The query is likely to be nearby the previous one.  Here we check to
      // see if it is within 5, 10 or 20 lines.  It can be far away in cases
      // where big comment blocks and vertical whitespace eat up lines but
      // contribute no tokens.
      if (SourceLineCache+5 < SourceLineCacheEnd) {
        if (SourceLineCache[5] > QueriedFilePos)
          SourceLineCacheEnd = SourceLineCache+5;
        else if (SourceLineCache+10 < SourceLineCacheEnd) {
          if (SourceLineCache[10] > QueriedFilePos)
            SourceLineCacheEnd = SourceLineCache+10;
          else if (SourceLineCache+20 < SourceLineCacheEnd) {
            if (SourceLineCache[20] > QueriedFilePos)
              SourceLineCacheEnd = SourceLineCache+20;
          }
        }
      }
    } else {
      SourceLineCacheEnd = SourceLineCache+LastLineNoResult+1;
    }
  }

  // If the spread is large, do a "radix" test as our initial guess, based on
  // the assumption that lines average to approximately the same length.
  // NOTE: This is currently disabled, as it does not appear to be profitable in
  // initial measurements.
  if (0 && SourceLineCacheEnd-SourceLineCache > 20) {
    unsigned FileLen = Content->SourceLineCache[Content->NumLines-1];

    // Take a stab at guessing where it is.
    unsigned ApproxPos = Content->NumLines*QueriedFilePos / FileLen;

    // Check for -10 and +10 lines.
    unsigned LowerBound = std::max(int(ApproxPos-10), 0);
    unsigned UpperBound = std::min(ApproxPos+10, FileLen);

    // If the computed lower bound is less than the query location, move it in.
    if (SourceLineCache < SourceLineCacheStart+LowerBound &&
        SourceLineCacheStart[LowerBound] < QueriedFilePos)
      SourceLineCache = SourceLineCacheStart+LowerBound;

    // If the computed upper bound is greater than the query location, move it.
    if (SourceLineCacheEnd > SourceLineCacheStart+UpperBound &&
        SourceLineCacheStart[UpperBound] >= QueriedFilePos)
      SourceLineCacheEnd = SourceLineCacheStart+UpperBound;
  }

  unsigned *Pos
    = std::lower_bound(SourceLineCache, SourceLineCacheEnd, QueriedFilePos);
  unsigned LineNo = Pos-SourceLineCacheStart;

  LastLineNoFileIDQuery = FileID;
  LastLineNoContentCache = Content;
  LastLineNoFilePos = QueriedFilePos;
  LastLineNoResult = LineNo;
  return LineNo;
}

/// PrintStats - Print statistics to stderr.
///
void SourceManager::PrintStats() const {
  std::cerr << "\n*** Source Manager Stats:\n";
  std::cerr << FileInfos.size() << " files mapped, " << MemBufferInfos.size()
            << " mem buffers mapped, " << FileIDs.size()
            << " file ID's allocated.\n";
  std::cerr << "  " << FileIDs.size() << " normal buffer FileID's, "
            << MacroIDs.size() << " macro expansion FileID's.\n";

  unsigned NumLineNumsComputed = 0;
  unsigned NumFileBytesMapped = 0;
  for (std::set<ContentCache>::const_iterator I =
       FileInfos.begin(), E = FileInfos.end(); I != E; ++I) {
    NumLineNumsComputed += I->SourceLineCache != 0;
    NumFileBytesMapped  += I->Buffer->getBufferSize();
  }

  std::cerr << NumFileBytesMapped << " bytes of files mapped, "
            << NumLineNumsComputed << " files with line #'s computed.\n";
}
<commit_msg>Updated a comment to hopefully silence a Lattner warning.<commit_after>//===--- SourceManager.cpp - Track and cache source files -----------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by Chris Lattner and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file implements the SourceManager interface.
//
//===----------------------------------------------------------------------===//

#include "clang/Basic/SourceManager.h"
#include "clang/Basic/FileManager.h"
#include "llvm/Config/config.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/System/Path.h"
#include "llvm/Bitcode/Serialize.h"
#include "llvm/Bitcode/Deserialize.h"
#include <algorithm>
#include <iostream>
#include <fcntl.h>
using namespace clang;
using namespace SrcMgr;
using llvm::MemoryBuffer;

ContentCache::~ContentCache() {
  delete Buffer;
  delete [] SourceLineCache;
}

// FIXME: REMOVE THESE
#include <unistd.h>
#include <sys/types.h>
#if !defined(_MSC_VER) && !defined(__MINGW32__)
#include <sys/uio.h>
#include <sys/fcntl.h>
#else
#include <io.h>
#endif
#include <cerrno>

static const MemoryBuffer *ReadFileFast(const FileEntry *FileEnt) {
#if 0
  // FIXME: Reintroduce this and zap this function once the common llvm stuff
  // is fast for the small case.
  return MemoryBuffer::getFile(FileEnt->getName(), strlen(FileEnt->getName()),
                               FileEnt->getSize());
#endif

  // If the file is larger than some threshold, use 'read', otherwise use mmap.
  if (FileEnt->getSize() >= 4096*4)
    return MemoryBuffer::getFile(FileEnt->getName(), strlen(FileEnt->getName()),
                                 0, FileEnt->getSize());

  MemoryBuffer *SB = MemoryBuffer::getNewUninitMemBuffer(FileEnt->getSize(),
                                                         FileEnt->getName());
  char *BufPtr = const_cast<char*>(SB->getBufferStart());

#if defined(LLVM_ON_WIN32)
  int FD = ::open(FileEnt->getName(), O_RDONLY|O_BINARY);
#else
  int FD = ::open(FileEnt->getName(), O_RDONLY);
#endif
  if (FD == -1) {
    delete SB;
    return 0;
  }

  unsigned BytesLeft = FileEnt->getSize();
  while (BytesLeft) {
    ssize_t NumRead = ::read(FD, BufPtr, BytesLeft);
    if (NumRead != -1) {
      BytesLeft -= NumRead;
      BufPtr += NumRead;
    } else if (errno == EINTR) {
      // try again
    } else {
      // error reading.
      close(FD);
      delete SB;
      return 0;
    }
  }
  close(FD);

  return SB;
}

/// getFileInfo - Create or return a cached FileInfo for the specified file.
///
const ContentCache* SourceManager::getContentCache(const FileEntry *FileEnt) {

  assert(FileEnt && "Didn't specify a file entry to use?");
  // Do we already have information about this file?
  std::set<ContentCache>::iterator I =
    FileInfos.lower_bound(ContentCache(FileEnt));

  if (I != FileInfos.end() && I->Entry == FileEnt)
    return &*I;

  // Nope, get information.
  const MemoryBuffer *File = ReadFileFast(FileEnt);
  if (File == 0)
    return 0;

  ContentCache& Entry = const_cast<ContentCache&>(*FileInfos.insert(I,FileEnt));

  Entry.Buffer = File;
  Entry.SourceLineCache = 0;
  Entry.NumLines = 0;
  return &Entry;
}

/// createMemBufferContentCache - Create a new ContentCache for the specified
///  memory buffer.  This does no caching.
const ContentCache*
SourceManager::createMemBufferContentCache(const MemoryBuffer *Buffer) {
  // Add a new ContentCache to the MemBufferInfos list and return it.  We
  // must default construct the object first that the instance actually
  // stored within MemBufferInfos actually owns the Buffer, and not any
  // temporary we would use in the call to "push_back".
  MemBufferInfos.push_back(ContentCache());
  ContentCache& Entry = const_cast<ContentCache&>(MemBufferInfos.back());
  Entry.Buffer = Buffer;
  return &Entry;
}

/// createFileID - Create a new fileID for the specified ContentCache and
/// include position.  This works regardless of whether the ContentCache
/// corresponds to a file or some other input source.
unsigned SourceManager::createFileID(const ContentCache *File,
                                     SourceLocation IncludePos) {
  // If FileEnt is really large (e.g. it's a large .i file), we may not be able
  // to fit an arbitrary position in the file in the FilePos field.  To handle
  // this, we create one FileID for each chunk of the file that fits in a
  // FilePos field.
  unsigned FileSize = File->Buffer->getBufferSize();
  if (FileSize+1 < (1 << SourceLocation::FilePosBits)) {
    FileIDs.push_back(FileIDInfo::get(IncludePos, 0, File));
    assert(FileIDs.size() < (1 << SourceLocation::FileIDBits) &&
           "Ran out of file ID's!");
    return FileIDs.size();
  }

  // Create one FileID for each chunk of the file.
  unsigned Result = FileIDs.size()+1;

  unsigned ChunkNo = 0;
  while (1) {
    FileIDs.push_back(FileIDInfo::get(IncludePos, ChunkNo++, File));

    if (FileSize+1 < (1 << SourceLocation::FilePosBits)) break;
    FileSize -= (1 << SourceLocation::FilePosBits);
  }

  assert(FileIDs.size() < (1 << SourceLocation::FileIDBits) &&
         "Ran out of file ID's!");
  return Result;
}

/// getInstantiationLoc - Return a new SourceLocation that encodes the fact
/// that a token from physloc PhysLoc should actually be referenced from
/// InstantiationLoc.
SourceLocation SourceManager::getInstantiationLoc(SourceLocation PhysLoc,
                                                  SourceLocation InstantLoc) {
  // The specified source location may be a mapped location, due to a macro
  // instantiation or #line directive.  Strip off this information to find out
  // where the characters are actually located.
  PhysLoc = getPhysicalLoc(PhysLoc);

  // Resolve InstantLoc down to a real logical location.
  InstantLoc = getLogicalLoc(InstantLoc);

  // If the last macro id is close to the currently requested location, try to
  // reuse it.  This implements a small cache.
  for (int i = MacroIDs.size()-1, e = MacroIDs.size()-6; i >= 0 && i != e; --i){
    MacroIDInfo &LastOne = MacroIDs[i];

    // The instanitation point and source physloc have to exactly match to reuse
    // (for now).  We could allow "nearby" instantiations in the future.
    if (LastOne.getInstantiationLoc() != InstantLoc ||
        LastOne.getPhysicalLoc().getFileID() != PhysLoc.getFileID())
      continue;

    // Check to see if the physloc of the token came from near enough to reuse.
    int PhysDelta = PhysLoc.getRawFilePos() -
                    LastOne.getPhysicalLoc().getRawFilePos();
    if (SourceLocation::isValidMacroPhysOffs(PhysDelta))
      return SourceLocation::getMacroLoc(i, PhysDelta, 0);
  }

  MacroIDs.push_back(MacroIDInfo::get(InstantLoc, PhysLoc));
  return SourceLocation::getMacroLoc(MacroIDs.size()-1, 0, 0);
}

/// getBufferData - Return a pointer to the start and end of the character
/// data for the specified FileID.
std::pair<const char*, const char*>
SourceManager::getBufferData(unsigned FileID) const {
  const llvm::MemoryBuffer *Buf = getBuffer(FileID);
  return std::make_pair(Buf->getBufferStart(), Buf->getBufferEnd());
}

/// getCharacterData - Return a pointer to the start of the specified location
/// in the appropriate MemoryBuffer.
const char *SourceManager::getCharacterData(SourceLocation SL) const {
  // Note that this is a hot function in the getSpelling() path, which is
  // heavily used by -E mode.
  SL = getPhysicalLoc(SL);

  return getContentCache(SL.getFileID())->Buffer->getBufferStart() +
         getFullFilePos(SL);
}

/// getColumnNumber - Return the column # for the specified file position.
/// this is significantly cheaper to compute than the line number.  This returns
/// zero if the column number isn't known.
unsigned SourceManager::getColumnNumber(SourceLocation Loc) const {
  unsigned FileID = Loc.getFileID();
  if (FileID == 0) return 0;

  unsigned FilePos = getFullFilePos(Loc);
  const MemoryBuffer *Buffer = getBuffer(FileID);
  const char *Buf = Buffer->getBufferStart();

  unsigned LineStart = FilePos;
  while (LineStart && Buf[LineStart-1] != '\n' && Buf[LineStart-1] != '\r')
    --LineStart;
  return FilePos-LineStart+1;
}

/// getSourceName - This method returns the name of the file or buffer that
/// the SourceLocation specifies.  This can be modified with #line directives,
/// etc.
const char *SourceManager::getSourceName(SourceLocation Loc) const {
  unsigned FileID = Loc.getFileID();
  if (FileID == 0) return "";
  return getContentCache(FileID)->Buffer->getBufferIdentifier();
}

static void ComputeLineNumbers(ContentCache* FI) DISABLE_INLINE;
static void ComputeLineNumbers(ContentCache* FI) {
  const MemoryBuffer *Buffer = FI->Buffer;

  // Find the file offsets of all of the *physical* source lines.  This does
  // not look at trigraphs, escaped newlines, or anything else tricky.
  std::vector<unsigned> LineOffsets;

  // Line #1 starts at char 0.
  LineOffsets.push_back(0);

  const unsigned char *Buf = (const unsigned char *)Buffer->getBufferStart();
  const unsigned char *End = (const unsigned char *)Buffer->getBufferEnd();
  unsigned Offs = 0;
  while (1) {
    // Skip over the contents of the line.
    // TODO: Vectorize this?  This is very performance sensitive for programs
    // with lots of diagnostics and in -E mode.
    const unsigned char *NextBuf = (const unsigned char *)Buf;
    while (*NextBuf != '\n' && *NextBuf != '\r' && *NextBuf != '\0')
      ++NextBuf;
    Offs += NextBuf-Buf;
    Buf = NextBuf;

    if (Buf[0] == '\n' || Buf[0] == '\r') {
      // If this is \n\r or \r\n, skip both characters.
      if ((Buf[1] == '\n' || Buf[1] == '\r') && Buf[0] != Buf[1])
        ++Offs, ++Buf;
      ++Offs, ++Buf;
      LineOffsets.push_back(Offs);
    } else {
      // Otherwise, this is a null.  If end of file, exit.
      if (Buf == End) break;
      // Otherwise, skip the null.
      ++Offs, ++Buf;
    }
  }
  LineOffsets.push_back(Offs);

  // Copy the offsets into the FileInfo structure.
  FI->NumLines = LineOffsets.size();
  FI->SourceLineCache = new unsigned[LineOffsets.size()];
  std::copy(LineOffsets.begin(), LineOffsets.end(), FI->SourceLineCache);
}

/// getLineNumber - Given a SourceLocation, return the physical line number
/// for the position indicated.  This requires building and caching a table of
/// line offsets for the MemoryBuffer, so this is not cheap: use only when
/// about to emit a diagnostic.
unsigned SourceManager::getLineNumber(SourceLocation Loc) {
  unsigned FileID = Loc.getFileID();
  if (FileID == 0) return 0;

  ContentCache* Content;

  if (LastLineNoFileIDQuery == FileID)
    Content = LastLineNoContentCache;
  else
    Content = const_cast<ContentCache*>(getContentCache(FileID));

  // If this is the first use of line information for this buffer, compute the
  /// SourceLineCache for it on demand.
  if (Content->SourceLineCache == 0)
    ComputeLineNumbers(Content);

  // Okay, we know we have a line number table.  Do a binary search to find the
  // line number that this character position lands on.
  unsigned *SourceLineCache = Content->SourceLineCache;
  unsigned *SourceLineCacheStart = SourceLineCache;
  unsigned *SourceLineCacheEnd = SourceLineCache + Content->NumLines;

  unsigned QueriedFilePos = getFullFilePos(Loc)+1;

  // If the previous query was to the same file, we know both the file pos from
  // that query and the line number returned.  This allows us to narrow the
  // search space from the entire file to something near the match.
  if (LastLineNoFileIDQuery == FileID) {
    if (QueriedFilePos >= LastLineNoFilePos) {
      SourceLineCache = SourceLineCache+LastLineNoResult-1;

      // The query is likely to be nearby the previous one.  Here we check to
      // see if it is within 5, 10 or 20 lines.  It can be far away in cases
      // where big comment blocks and vertical whitespace eat up lines but
      // contribute no tokens.
      if (SourceLineCache+5 < SourceLineCacheEnd) {
        if (SourceLineCache[5] > QueriedFilePos)
          SourceLineCacheEnd = SourceLineCache+5;
        else if (SourceLineCache+10 < SourceLineCacheEnd) {
          if (SourceLineCache[10] > QueriedFilePos)
            SourceLineCacheEnd = SourceLineCache+10;
          else if (SourceLineCache+20 < SourceLineCacheEnd) {
            if (SourceLineCache[20] > QueriedFilePos)
              SourceLineCacheEnd = SourceLineCache+20;
          }
        }
      }
    } else {
      SourceLineCacheEnd = SourceLineCache+LastLineNoResult+1;
    }
  }

  // If the spread is large, do a "radix" test as our initial guess, based on
  // the assumption that lines average to approximately the same length.
  // NOTE: This is currently disabled, as it does not appear to be profitable in
  // initial measurements.
  if (0 && SourceLineCacheEnd-SourceLineCache > 20) {
    unsigned FileLen = Content->SourceLineCache[Content->NumLines-1];

    // Take a stab at guessing where it is.
    unsigned ApproxPos = Content->NumLines*QueriedFilePos / FileLen;

    // Check for -10 and +10 lines.
    unsigned LowerBound = std::max(int(ApproxPos-10), 0);
    unsigned UpperBound = std::min(ApproxPos+10, FileLen);

    // If the computed lower bound is less than the query location, move it in.
    if (SourceLineCache < SourceLineCacheStart+LowerBound &&
        SourceLineCacheStart[LowerBound] < QueriedFilePos)
      SourceLineCache = SourceLineCacheStart+LowerBound;

    // If the computed upper bound is greater than the query location, move it.
    if (SourceLineCacheEnd > SourceLineCacheStart+UpperBound &&
        SourceLineCacheStart[UpperBound] >= QueriedFilePos)
      SourceLineCacheEnd = SourceLineCacheStart+UpperBound;
  }

  unsigned *Pos
    = std::lower_bound(SourceLineCache, SourceLineCacheEnd, QueriedFilePos);
  unsigned LineNo = Pos-SourceLineCacheStart;

  LastLineNoFileIDQuery = FileID;
  LastLineNoContentCache = Content;
  LastLineNoFilePos = QueriedFilePos;
  LastLineNoResult = LineNo;
  return LineNo;
}

/// PrintStats - Print statistics to stderr.
///
void SourceManager::PrintStats() const {
  std::cerr << "\n*** Source Manager Stats:\n";
  std::cerr << FileInfos.size() << " files mapped, " << MemBufferInfos.size()
            << " mem buffers mapped, " << FileIDs.size()
            << " file ID's allocated.\n";
  std::cerr << "  " << FileIDs.size() << " normal buffer FileID's, "
            << MacroIDs.size() << " macro expansion FileID's.\n";

  unsigned NumLineNumsComputed = 0;
  unsigned NumFileBytesMapped = 0;
  for (std::set<ContentCache>::const_iterator I =
       FileInfos.begin(), E = FileInfos.end(); I != E; ++I) {
    NumLineNumsComputed += I->SourceLineCache != 0;
    NumFileBytesMapped  += I->Buffer->getBufferSize();
  }

  std::cerr << NumFileBytesMapped << " bytes of files mapped, "
            << NumLineNumsComputed << " files with line #'s computed.\n";
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: skeletoncommon.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: ihi $ $Date: 2006-08-01 16:24:36 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef INCLUDED_UNODEVTOOLS_SOURCE_SKELETONMAKER_SKELETONCOMMON_HXX
#define INCLUDED_UNODEVTOOLS_SOURCE_SKELETONMAKER_SKELETONCOMMON_HXX

#ifndef _RTL_STRING_HXX_
#include "rtl/string.hxx"
#endif
#ifndef INCLUDED_registry_reader_hxx
#include "registry/reader.hxx"
#endif
#ifndef INCLUDED_CODEMAKER_TYPEMANAGER_HXX
#include "codemaker/typemanager.hxx"
#endif
#ifndef INCLUDED_CODEMAKER_UNOTYPE_HXX
#include "codemaker/unotype.hxx"
#endif

#include <fstream>
#include <hash_set>
#include <hash_map>

namespace skeletonmaker {

struct ProgramOptions {
    ProgramOptions(): java5(true), all(false), dump(false), license(false),
                      shortnames(false), supportpropertysetmixin(false),
                      backwardcompatible(false), language(1), componenttype(1) {}

    bool java5;
    bool all;
    bool dump;
    bool license;
    bool shortnames;
    bool supportpropertysetmixin;
    bool backwardcompatible;
    // language specifier - is extendable
    // 1 = Java
    // 2 = C++
    short language;
    // component type
    // 1 = default UNO component - is extendable
    // 2 = calc add-in
    // 3 = add-on
    short componenttype;
    rtl::OString outputpath;
    rtl::OString implname;
};

// typedef ::std::hash_map< ::rtl::OString,
//                          ::std::pair< rtl::OString, sal_Int16 >,
//                          rtl::OStringHash > StringPairHashMap;

typedef ::std::vector< ::std::pair< rtl::OString,
                     ::std::pair< rtl::OString, sal_Int16 > > > AttributeInfo;

/**
   print the standard OpenOffice.org license header

   @param o specifies the output stream
   @param filename specifies the source file name
*/
void printLicenseHeader(std::ostream& o, rtl::OString const & filename);

/**
   create dependent on the output path, the implementation name and the
   extension a new output file. If output path is equal "stdout" the tool
   generates the output to standard out.

   @param options the program options including the output path and the
                  implementation name
   @param extension specifies the file extensions (e.g. .cxx or .java)
   @param ppOutputStream out parameter returning the output stream
   @param targetSourceFileName out parameter returning the generated file name
                               constructed on base of the output path, the
                               implementation name and the extension
   @param tmpSourceFileName out parameter returning the temporary file name based
                            on the output path and a generated temporary file name.
   @return true if output is generated to standard out or else false
*/
bool getOutputStream(ProgramOptions const & options,
                     rtl::OString const & extension,
                     std::ostream** ppOutputStream,
                     rtl::OString & targetSourceFileName,
                     rtl::OString & tmpSourceFileName);

codemaker::UnoType::Sort decomposeResolveAndCheck(
    TypeManager const & manager, rtl::OString const & type,
    bool resolveTypedefs, bool allowVoid, bool allowExtraEntities,
    RTTypeClass * typeClass, rtl::OString * name, sal_Int32 * rank,
    std::vector< rtl::OString > * arguments);

void checkType(TypeManager const & manager,
               rtl::OString const & type,
               std::hash_set< rtl::OString, rtl::OStringHash >& interfaceTypes,
               std::hash_set< rtl::OString, rtl::OStringHash >& serviceTypes,
               AttributeInfo& properties);

void checkDefaultInterfaces(
    std::hash_set< rtl::OString, rtl::OStringHash >& interfaces,
    const std::hash_set< rtl::OString, rtl::OStringHash >& services,
    const rtl::OString & propertyhelper);

rtl::OString checkPropertyHelper(
    ProgramOptions const & options, TypeManager const & manager,
    const std::hash_set< rtl::OString, rtl::OStringHash >& services,
    const std::hash_set< rtl::OString, rtl::OStringHash >& interfaces,
    AttributeInfo& attributes,
    std::hash_set< rtl::OString, rtl::OStringHash >& propinterfaces);

/**
   checks whether the return and parameters types are valid and allowed
   calc add-in type. The function throws a CannotDumpException with an
   detailed error description which type is wrong

   @param manager a type manager
   @param reader a registry type reader of an interface defining
                 calc add-in functions
*/
void checkAddInTypes(TypeManager const & manager,
                     typereg::Reader const & reader);

/**
   checks if XComponent have to be supported, if yes it removes it from the
   supported interfaces list becuase it becmoes implmented by the appropriate
   helper

   @param manager a type manager
   @param interfaces a list of interfaces which should be implemented

   @return true if XComponent have to be supported
*/
bool checkXComponentSupport(TypeManager const & manager,
         std::hash_set< rtl::OString, rtl::OStringHash >& interfaces);

sal_uInt16 checkAdditionalPropertyFlags(typereg::Reader const & reader,
                                        sal_uInt16 field, sal_uInt16 method);

void generateFunctionParameterMap(std::ostream& o,
         ProgramOptions const & options,
         TypeManager const & manager,
         const std::hash_set< ::rtl::OString, ::rtl::OStringHash >& interfaces);

}

#endif // INCLUDED_UNODEVTOOLS_SOURCE_SKELETONMAKER_SKELETONCOMMON_HXX

<commit_msg>INTEGRATION: CWS jsc14 (1.5.8); FILE MERGED 2006/10/27 14:44:37 jsc 1.5.8.1: #i69760# prepare code base for add-ons<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: skeletoncommon.hxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: kz $ $Date: 2006-11-06 14:43:16 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef INCLUDED_UNODEVTOOLS_SOURCE_SKELETONMAKER_SKELETONCOMMON_HXX
#define INCLUDED_UNODEVTOOLS_SOURCE_SKELETONMAKER_SKELETONCOMMON_HXX

#ifndef _RTL_STRING_HXX_
#include "rtl/string.hxx"
#endif
#ifndef INCLUDED_registry_reader_hxx
#include "registry/reader.hxx"
#endif
#ifndef INCLUDED_CODEMAKER_TYPEMANAGER_HXX
#include "codemaker/typemanager.hxx"
#endif
#ifndef INCLUDED_CODEMAKER_UNOTYPE_HXX
#include "codemaker/unotype.hxx"
#endif

#include <fstream>
#include <hash_set>
#include <map>

namespace skeletonmaker {

typedef ::std::map< ::rtl::OString, ::std::vector< ::rtl::OString >,
                    ::std::less< ::rtl::OString > > ProtocolCmdMap;

typedef ::std::vector< ::std::pair< rtl::OString,
                     ::std::pair< rtl::OString, sal_Int16 > > > AttributeInfo;

struct ProgramOptions {
    ProgramOptions(): java5(true), all(false), dump(false), license(false),
                      shortnames(false), supportpropertysetmixin(false),
                      backwardcompatible(false), language(1), componenttype(1) {}

    bool java5;
    bool all;
    bool dump;
    bool license;
    bool shortnames;
    bool supportpropertysetmixin;
    bool backwardcompatible;
    // language specifier - is extendable
    // 1 = Java
    // 2 = C++
    short language;
    // component type
    // 1 = default UNO component - is extendable
    // 2 = calc add-in
    // 3 = add-on
    short componenttype;
    rtl::OString outputpath;
    rtl::OString implname;
    ProtocolCmdMap protocolCmdMap;
};

/**
   print the standard OpenOffice.org license header

   @param o specifies the output stream
   @param filename specifies the source file name
*/
void printLicenseHeader(std::ostream& o, rtl::OString const & filename);

/**
   create dependent on the output path, the implementation name and the
   extension a new output file. If output path is equal "stdout" the tool
   generates the output to standard out.

   @param options the program options including the output path and the
                  implementation name
   @param extension specifies the file extensions (e.g. .cxx or .java)
   @param ppOutputStream out parameter returning the output stream
   @param targetSourceFileName out parameter returning the generated file name
                               constructed on base of the output path, the
                               implementation name and the extension
   @param tmpSourceFileName out parameter returning the temporary file name based
                            on the output path and a generated temporary file name.
   @return true if output is generated to standard out or else false
*/
bool getOutputStream(ProgramOptions const & options,
                     rtl::OString const & extension,
                     std::ostream** ppOutputStream,
                     rtl::OString & targetSourceFileName,
                     rtl::OString & tmpSourceFileName);

codemaker::UnoType::Sort decomposeResolveAndCheck(
    TypeManager const & manager, rtl::OString const & type,
    bool resolveTypedefs, bool allowVoid, bool allowExtraEntities,
    RTTypeClass * typeClass, rtl::OString * name, sal_Int32 * rank,
    std::vector< rtl::OString > * arguments);

void checkType(TypeManager const & manager,
               rtl::OString const & type,
               std::hash_set< rtl::OString, rtl::OStringHash >& interfaceTypes,
               std::hash_set< rtl::OString, rtl::OStringHash >& serviceTypes,
               AttributeInfo& properties);

void checkDefaultInterfaces(
    std::hash_set< rtl::OString, rtl::OStringHash >& interfaces,
    const std::hash_set< rtl::OString, rtl::OStringHash >& services,
    const rtl::OString & propertyhelper);

rtl::OString checkPropertyHelper(
    ProgramOptions const & options, TypeManager const & manager,
    const std::hash_set< rtl::OString, rtl::OStringHash >& services,
    const std::hash_set< rtl::OString, rtl::OStringHash >& interfaces,
    AttributeInfo& attributes,
    std::hash_set< rtl::OString, rtl::OStringHash >& propinterfaces);

/**
   checks whether the return and parameters types are valid and allowed
   calc add-in type. The function throws a CannotDumpException with an
   detailed error description which type is wrong

   @param manager a type manager
   @param reader a registry type reader of an interface defining
                 calc add-in functions
*/
void checkAddInTypes(TypeManager const & manager,
                     typereg::Reader const & reader);

/**
   checks if XComponent have to be supported, if yes it removes it from the
   supported interfaces list becuase it becmoes implmented by the appropriate
   helper

   @param manager a type manager
   @param interfaces a list of interfaces which should be implemented

   @return true if XComponent have to be supported
*/
bool checkXComponentSupport(TypeManager const & manager,
         std::hash_set< rtl::OString, rtl::OStringHash >& interfaces);

sal_uInt16 checkAdditionalPropertyFlags(typereg::Reader const & reader,
                                        sal_uInt16 field, sal_uInt16 method);

void generateFunctionParameterMap(std::ostream& o,
         ProgramOptions const & options,
         TypeManager const & manager,
         const std::hash_set< ::rtl::OString, ::rtl::OStringHash >& interfaces);

}

#endif // INCLUDED_UNODEVTOOLS_SOURCE_SKELETONMAKER_SKELETONCOMMON_HXX

<|endoftext|>


<commit_before>/*
 * Copyright 2012 Matthew McCormick
 * Copyright 2013 Justin Crawford <Justasic@gmail.com>
 * Copyright 2015 Pawel 'l0ner' Soltys
 *
 * 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 <string>
#include <sstream>
#include <mach/mach.h>
#include <sys/sysctl.h> // for sysctl

#include "memory.h"
#include "luts.h"
#include "conversions.h"

std::string mem_string( bool use_colors )
{
  std::ostringstream oss;

  // These values are in bytes
  int64_t total_mem;
  int64_t used_mem;
  int64_t unused_mem;

  vm_size_t page_size;
  mach_port_t mach_port;
  mach_msg_type_number_t count;
  vm_statistics_data_t vm_stats;

  // Get total physical memory
  int mib[2];
  mib[0] = CTL_HW;
  mib[1] = HW_MEMSIZE;
  size_t length = sizeof( int64_t );
  sysctl( mib, 2, &total_mem, &length, NULL, 0 );

  mach_port = mach_host_self();
  count = sizeof( vm_stats ) / sizeof( natural_t );
  if( KERN_SUCCESS == host_page_size( mach_port, &page_size ) &&
      KERN_SUCCESS == host_statistics( mach_port, HOST_VM_INFO,
        ( host_info_t )&vm_stats, &count ) )
  {
    unused_mem = ( int64_t )vm_stats.free_count * ( int64_t )page_size;

    used_mem = ( ( int64_t )vm_stats.active_count +
        ( int64_t )vm_stats.inactive_count + ( int64_t )vm_stats.wire_count
        ) * ( int64_t )page_size;
  }

  if( use_colors )
  {
    oss << mem_lut[( 100 * used_mem ) / total_mem];
  }

  oss << convert_unit( used_mem, MEGABYTES ) << '/'
	<< convert_unit( total_mem, MEGABYTES ) << "MB";

  if( use_colors )
  {
    oss << "#[fg=default,bg=default]";
  }

  return oss.str();
}
<commit_msg>OSX: exclude cached memory from used<commit_after>/*
 * Copyright 2012 Matthew McCormick
 * Copyright 2013 Justin Crawford <Justasic@gmail.com>
 * Copyright 2015 Pawel 'l0ner' Soltys
 *
 * 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 <string>
#include <sstream>
#include <mach/mach.h>
#include <sys/sysctl.h> // for sysctl

#include "memory.h"
#include "luts.h"
#include "conversions.h"

std::string mem_string( bool use_colors )
{
  std::ostringstream oss;

  // These values are in bytes
  u_int64_t total_mem;
  u_int64_t used_mem;
  //u_int64_t unused_mem;

  vm_size_t page_size;
  vm_statistics_data_t vm_stats;

  // Get total physical memory
  int mib[] = { CTL_HW, HW_MEMSIZE };
  size_t length = sizeof( total_mem );
  sysctl( mib, 2, &total_mem, &length, NULL, 0 );

  mach_port_t mach_port = mach_host_self();
  mach_msg_type_number_t count = sizeof( vm_stats ) / sizeof( natural_t );
  if( KERN_SUCCESS == host_page_size( mach_port, &page_size ) &&
      KERN_SUCCESS == host_statistics( mach_port, HOST_VM_INFO,
        ( host_info_t )&vm_stats, &count )
    )
  {
    //unused_mem = static_cast<u_int64_t>( vm_stats.free_count * page_size );

    used_mem = static_cast<u_int64_t>(
        ( vm_stats.active_count + vm_stats.wire_count ) * page_size);
  }

  if( use_colors )
  {
    oss << mem_lut[( 100 * used_mem ) / total_mem];
  }

  oss << convert_unit( used_mem, MEGABYTES ) << '/'
    << convert_unit( total_mem, MEGABYTES ) << "MB";

  if( use_colors )
  {
    oss << "#[fg=default,bg=default]";
  }

  return oss.str();
}
<|endoftext|>


<commit_before>#include "headers/mainwindow.h"
#include "headers/cryptogame.h"
#include "headers/primefactorization.h"
#include "headers/generateprimes.h"
#include "ui_mainwindow.h"
#include "QPushButton"

#include "iostream" //for debugging

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_GPUCheckBox_clicked()
{

}

void MainWindow::on_pushButton_clicked()
{
    std::cout<<"Start the game."<<std::endl;
    cryptogame agame = cryptogame();
    std::cout<<agame.getEncryptedMessage()<<std::endl;
}

void MainWindow::on_factorPrimesButton_clicked()
{
	using std::cout;
	using std::endl;

	cout<< "'Factor Primes' button pressed" <<endl;

	GeneratePrimes gp = GeneratePrimes(10000);
	gp.generate();
	long composite = gp.randomPrime() * gp.randomPrime();

	cout << "Number to factor: " << endl << composite;

	PrimeFactorization pf = PrimeFactorization();
	long* primes = pf.bruteForceFactor(composite);

	cout << "=" << primes[0] <<	"*" << primes[1] << endl;
}
<commit_msg>updated mainwindow to work with updated prime fact.<commit_after>#include "headers/mainwindow.h"
#include "headers/cryptogame.h"
#include "headers/primefactorization.h"
#include "headers/generateprimes.h"
#include "ui_mainwindow.h"
#include "QPushButton"

#include "iostream" //for debugging

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_GPUCheckBox_clicked()
{

}

void MainWindow::on_pushButton_clicked()
{
    std::cout<<"Start the game."<<std::endl;
    cryptogame agame = cryptogame();
    std::cout<<agame.getEncryptedMessage()<<std::endl;
}

void MainWindow::on_factorPrimesButton_clicked()
{
	using std::cout;
	using std::endl;

	cout<< "'Factor Primes' button pressed" <<endl;
	mpz_class composite, p, q;
	GeneratePrimes gp = GeneratePrimes(10000);
	gp.generate();
	p = gp.randomPrime();
	q = gp.randomPrime();
	composite = p * q;

	cout << p.get_str(10) << " * " << q.get_str(10) << " = " << composite.get_str(10) << endl;

	cout << "Number to factor: " << composite.get_str(10) << endl;

	PrimeFactorization pf = PrimeFactorization();
	pf.bruteForceFactor(composite);

	cout << "factor 1: " << pf.p1.get_str(10) << endl;
	cout << "factor 2: " << pf.p2.get_str(10) << endl;
}
<|endoftext|>


<commit_before>/*
This file is part of Bohrium and copyright (c) 2012 the Bohrium
team <http://www.bh107.org>.

Bohrium is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3
of the License, or (at your option) any later version.

Bohrium is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the
GNU Lesser General Public License along with Bohrium.

If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

#include <bh_view.hpp>

std::vector<unsigned char> compress(const bh_view &ary, const std::string &param);

std::vector<unsigned char> compress(const bh_base &ary, const std::string &param = "");

void uncompress(const std::vector<unsigned char> &data, bh_view &ary, const std::string &param);

void uncompress(const std::vector<unsigned char> &data, bh_base &ary, const std::string &param = "");

<commit_msg>proxy: added some doc to compress()<commit_after>/*
This file is part of Bohrium and copyright (c) 2012 the Bohrium
team <http://www.bh107.org>.

Bohrium is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3
of the License, or (at your option) any later version.

Bohrium is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the
GNU Lesser General Public License along with Bohrium.

If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

#include <bh_view.hpp>

/** Compress `ary`
 *
 * @param ary    The array view to compress, the view MUST represent the whole base array and be contiguous
 * @param param  A string of parameters to parsed through to the compress library
 * @return       The compressed bytes
 */
std::vector<unsigned char> compress(const bh_view &ary, const std::string &param);

/** Compress `ary`
 *
 * @param ary    The array base to compress
 * @param param  A string of parameters to parsed through to the compress library
 * @return       The compressed bytes
 */
std::vector<unsigned char> compress(const bh_base &ary, const std::string &param = "");

/** Uncompress `data` into `ary`
 *
 * @param data   The byte of compressed data
 * @param ary    The output array
 * @param param  A string of parameters to parsed through to the compress library
 */
void uncompress(const std::vector<unsigned char> &data, bh_view &ary, const std::string &param);

void uncompress(const std::vector<unsigned char> &data, bh_base &ary, const std::string &param = "");
<|endoftext|>


<commit_before>
#include "potentialfunctioncbspl.h"

PotentialFunctionCBSPL::PotentialFunctionCBSPL(const int nlam_,
        const int ncutcoeff_, const double min_, const double max_) :
                        PotentialFunction(nlam_,min_,max_) {

    /* Here nlam_ is the total number of coeff values that are to be optimized
     * To ensure that potential and force go to zero smoothly near cut-off,
     * as suggested in Ref. PCCP, 11, 1901, 2009, coeff values leading up to
     * cut-off and beyond take a value of zero.
     *
     * Since region less than rmin is not sampled sufficiently for stability
     * first _nexcl coefficients are not optimized instead their values are
     * extrapolated from first statistically significant knot values near rmin
     */

    // number of break points = _lam.size() - 2
    _nbreak = _lam.size() - 2;

     _dr = ( _cut_off )/( double (_nbreak - 1) );

    // break point locations
    // since ncoeff = nbreak +2 , r values for last two coefficients are also
    // computed
    _rbreak.resize(_lam.size(),false);

    _rbreak.clear();

    for( int i = 0; i < _lam.size(); i++)
        _rbreak(i) = i*_dr;

    _nexcl = min( int( ( _min )/_dr ), _nbreak - 2 );

    _ncutcoeff = ncutcoeff_;

    _M.resize(4,4,false);
    _M.clear();
    _M(0,0) =  1.0; _M(0,1) =  4.0; _M(0,2) =  1.0; _M(0,3) = 0.0;
    _M(1,0) = -3.0; _M(1,1) =  0.0; _M(1,2) =  3.0; _M(1,3) = 0.0;
    _M(2,0) =  3.0; _M(2,1) = -6.0; _M(2,2) =  3.0; _M(2,3) = 0.0;
    _M(3,0) = -1.0; _M(3,1) =  3.0; _M(3,2) = -3.0; _M(3,3) = 1.0;
    _M /= 6.0;

}

int PotentialFunctionCBSPL::getOptParamSize() const {

    return _lam.size() - _nexcl - _ncutcoeff;
}

void PotentialFunctionCBSPL::setParam(string filename) {

        Table param;
        param.Load(filename);

        _lam.clear();

        if( param.size() != _lam.size()) {

            throw std::runtime_error("Potential parameters size mismatch!\n"
                    "Check input parameter file \""
                    + filename + "\" \nThere should be "
                    + boost::lexical_cast<string>( _lam.size() ) + " parameters");
        } else {
            // force last _ncutcoeff to be zero
            for( int i = 0; i < _lam.size() - _ncutcoeff; i++){

                _rbreak(i) = param.x(i);
                _lam(i) = param.y(i);

            }

        }

    }

void PotentialFunctionCBSPL::SaveParam(const string& filename){

    extrapolExclParam();

    Table param;
    param.SetHasYErr(false);
    param.resize(_lam.size(), false);

    for (int i = 0; i < _lam.size(); i++){

        param.set(i, _rbreak(i), _lam(i), 'i');
    }

    param.Save(filename);

}

void PotentialFunctionCBSPL::SavePotTab(const string& filename,
        const double step) {

    extrapolExclParam();

    PotentialFunction::SavePotTab(filename,step);

}

void PotentialFunctionCBSPL::extrapolExclParam(){

    // extrapolate first _nexcl knot values using exponential extrapolation
    // u(r) = a * exp( b * r)
    // a = u0 * exp ( - m * r0/u0 )
    // b = m/u0
    // m = (u1-u0)/(r1-r0)

    double u0 = _lam(_nexcl);
    double r0 = _rbreak(_nexcl);
    double m = (_lam(_nexcl + 1) - _lam(_nexcl)) /
            (_rbreak(_nexcl + 1) - _rbreak(_nexcl));
    double a = u0 * exp(-m * r0 / u0);
    double b = m / u0;

    for (int i = 0; i < _nexcl; i++) {

        double r = _rbreak(i);
        double u = a * exp(b * r);
        _lam(i) = u;

    }

}

void PotentialFunctionCBSPL::setOptParam(const int i, const double val){

    _lam( i + _nexcl ) = val;

}

double PotentialFunctionCBSPL::getOptParam(const int i) const{

    return _lam( i + _nexcl );

}

double PotentialFunctionCBSPL::CalculateF (const double r) const {

    if( r >= _min && r <= _cut_off){

        ub::vector<double> R;
        ub::vector<double> B;

        int indx = min( int( r /_dr ) , _nbreak-2 );

        double rk = indx*_dr;

        double t = ( r - rk)/_dr;

        R.resize(4,false); R.clear();

        R(0) = 1.0; R(1) = t; R(2) = t*t; R(3) = t*t*t;

        ub::vector<double> RM = ub::prod(R,_M);

        B.resize(4,false); B.clear();

        B(0) = _lam(indx); B(1) = _lam(indx+1); B(2) = _lam(indx+2);
        B(3) = _lam(indx+3);

        double u = ub::inner_prod(B,RM);

        return u;

    } else {

        return 0.0;

    }

}
    // calculate first derivative w.r.t. ith parameter
double PotentialFunctionCBSPL::CalculateDF(const int i, const double r) const{

    // since first _nexcl parameters are not optimized for stability reasons
    //i = i + _nexcl;

    if ( r >= _min && r <= _cut_off ) {

        int indx = min( int( ( r )/_dr ), _nbreak-2 );

        if ( i + _nexcl >= indx && i + _nexcl <= indx+3 ){

            ub::vector<double> R;

            double rk = indx*_dr;

            double t = ( r - rk)/_dr;

            R.resize(4,false); R.clear();

            R(0) = 1.0; R(1) = t; R(2) = t*t; R(3) = t*t*t;

            ub::vector<double> RM = ub::prod(R,_M);

            return RM(i + _nexcl-indx);

        }else{

            return 0.0;

        }

    } else {

        return 0;

    }
}
    // calculate second derivative w.r.t. ith parameter
double PotentialFunctionCBSPL::CalculateD2F(const int i, const int j,
        const double r) const {

    // for cubic B-SPlines D2F is zero for all lamdas
    return 0.0;

}
<commit_msg>changed no. of excluded parameters for cbspl excluding the interval containing rmin seems to work well rather than including it<commit_after>
#include "potentialfunctioncbspl.h"

PotentialFunctionCBSPL::PotentialFunctionCBSPL(const int nlam_,
        const int ncutcoeff_, const double min_, const double max_) :
                        PotentialFunction(nlam_,min_,max_) {

    /* Here nlam_ is the total number of coeff values that are to be optimized
     * To ensure that potential and force go to zero smoothly near cut-off,
     * as suggested in Ref. PCCP, 11, 1901, 2009, coeff values leading up to
     * cut-off and beyond take a value of zero.
     *
     * Since region less than rmin is not sampled sufficiently for stability
     * first _nexcl coefficients are not optimized instead their values are
     * extrapolated from first statistically significant knot values near rmin
     */

    // number of break points = _lam.size() - 2
    _nbreak = _lam.size() - 2;

     _dr = ( _cut_off )/( double (_nbreak - 1) );

    // break point locations
    // since ncoeff = nbreak +2 , r values for last two coefficients are also
    // computed
    _rbreak.resize(_lam.size(),false);

    _rbreak.clear();

    for( int i = 0; i < _lam.size(); i++)
        _rbreak(i) = i*_dr;

    _nexcl = min( int( ( _min )/_dr ), _nbreak - 2 ) + 1;

    _ncutcoeff = ncutcoeff_;

    _M.resize(4,4,false);
    _M.clear();
    _M(0,0) =  1.0; _M(0,1) =  4.0; _M(0,2) =  1.0; _M(0,3) = 0.0;
    _M(1,0) = -3.0; _M(1,1) =  0.0; _M(1,2) =  3.0; _M(1,3) = 0.0;
    _M(2,0) =  3.0; _M(2,1) = -6.0; _M(2,2) =  3.0; _M(2,3) = 0.0;
    _M(3,0) = -1.0; _M(3,1) =  3.0; _M(3,2) = -3.0; _M(3,3) = 1.0;
    _M /= 6.0;

}

int PotentialFunctionCBSPL::getOptParamSize() const {

    return _lam.size() - _nexcl - _ncutcoeff;
}

void PotentialFunctionCBSPL::setParam(string filename) {

        Table param;
        param.Load(filename);

        _lam.clear();

        if( param.size() != _lam.size()) {

            throw std::runtime_error("Potential parameters size mismatch!\n"
                    "Check input parameter file \""
                    + filename + "\" \nThere should be "
                    + boost::lexical_cast<string>( _lam.size() ) + " parameters");
        } else {
            // force last _ncutcoeff to be zero
            for( int i = 0; i < _lam.size() - _ncutcoeff; i++){

                _rbreak(i) = param.x(i);
                _lam(i) = param.y(i);

            }

        }

    }

void PotentialFunctionCBSPL::SaveParam(const string& filename){

    extrapolExclParam();

    Table param;
    param.SetHasYErr(false);
    param.resize(_lam.size(), false);

    for (int i = 0; i < _lam.size(); i++){

        param.set(i, _rbreak(i), _lam(i), 'i');
    }

    param.Save(filename);

}

void PotentialFunctionCBSPL::SavePotTab(const string& filename,
        const double step) {

    extrapolExclParam();

    PotentialFunction::SavePotTab(filename,step);

}

void PotentialFunctionCBSPL::extrapolExclParam(){

    // extrapolate first _nexcl knot values using exponential extrapolation
    // u(r) = a * exp( b * r)
    // a = u0 * exp ( - m * r0/u0 )
    // b = m/u0
    // m = (u1-u0)/(r1-r0)

    double u0 = _lam(_nexcl);
    double r0 = _rbreak(_nexcl);
    double m = (_lam(_nexcl + 1) - _lam(_nexcl)) /
            (_rbreak(_nexcl + 1) - _rbreak(_nexcl));
    double a = u0 * exp(-m * r0 / u0);
    double b = m / u0;

    for (int i = 0; i < _nexcl; i++) {

        double r = _rbreak(i);
        double u = a * exp(b * r);
        _lam(i) = u;

    }

}

void PotentialFunctionCBSPL::setOptParam(const int i, const double val){

    _lam( i + _nexcl ) = val;

}

double PotentialFunctionCBSPL::getOptParam(const int i) const{

    return _lam( i + _nexcl );

}

double PotentialFunctionCBSPL::CalculateF (const double r) const {

    if( r >= _min && r <= _cut_off){

        ub::vector<double> R;
        ub::vector<double> B;

        int indx = min( int( r /_dr ) , _nbreak-2 );

        double rk = indx*_dr;

        double t = ( r - rk)/_dr;

        R.resize(4,false); R.clear();

        R(0) = 1.0; R(1) = t; R(2) = t*t; R(3) = t*t*t;

        ub::vector<double> RM = ub::prod(R,_M);

        B.resize(4,false); B.clear();

        B(0) = _lam(indx); B(1) = _lam(indx+1); B(2) = _lam(indx+2);
        B(3) = _lam(indx+3);

        double u = ub::inner_prod(B,RM);

        return u;

    } else {

        return 0.0;

    }

}
    // calculate first derivative w.r.t. ith parameter
double PotentialFunctionCBSPL::CalculateDF(const int i, const double r) const{

    // since first _nexcl parameters are not optimized for stability reasons
    //i = i + _nexcl;

    if ( r >= _min && r <= _cut_off ) {

        int indx = min( int( ( r )/_dr ), _nbreak-2 );

        if ( i + _nexcl >= indx && i + _nexcl <= indx+3 ){

            ub::vector<double> R;

            double rk = indx*_dr;

            double t = ( r - rk)/_dr;

            R.resize(4,false); R.clear();

            R(0) = 1.0; R(1) = t; R(2) = t*t; R(3) = t*t*t;

            ub::vector<double> RM = ub::prod(R,_M);

            return RM(i + _nexcl-indx);

        }else{

            return 0.0;

        }

    } else {

        return 0;

    }
}
    // calculate second derivative w.r.t. ith parameter
double PotentialFunctionCBSPL::CalculateD2F(const int i, const int j,
        const double r) const {

    // for cubic B-SPlines D2F is zero for all lamdas
    return 0.0;

}
<|endoftext|>


<commit_before>#include <ncurses.h>
#include <string>
#include <vector>

#include "configuration.hh"
#include "int_to_str.hh"
#include "newmove.hh"
#include "show_message.hh"

int from_visual(const std::string& cont, int x) {
    if(cont.size() == 0) return 0;
    int count = 0,
        til = 0;
    for(int i = 0; i < cont.length(); i++) {
        int len;
        if(cont[i] == '\t') {
            len = TAB_SIZE() - 1 - til;
            til = 0;
        } else {
            len = 1;
            til++;
            til %= TAB_SIZE();
        }
        count += len;
        if(count >= x) {
            return i;
        }
    }
}

int to_visual(const std::string& cont, int x) {
    int til = 0,
        xx = -1;
    for(std::string::const_iterator i = cont.begin();
                i <= cont.begin() + x; i++) {
        if(*i == '\t') {
            xx += TAB_SIZE() - til;
            til = 0;
        } else {
            til++;
            til %= TAB_SIZE();
            xx++;
        }
    }
    return xx;
}

void redrawyx(contents& contents) {
    move(contents.y,to_visual((*contents.cont)[contents.y],contents.x));
}

void mvline(contents& contents, unsigned long line) {
    mvrel(contents, line - contents.y, 0);
}
void mv(contents& contents, unsigned long _y, unsigned long _x) {
    mvrel(contents, _y - contents.y, _x - contents.x);
}

void mvrel(contents& contents, long y, long x) {
    if(y < 0) mvu(contents,-y);
    else      mvd(contents, y);
    if(x < 0) mvb(contents,-x);
    else      mvf(contents, x);
}

void mvcol(contents& contents, unsigned long col) {
    unsigned int len = (*contents.cont)[contents.y].length();
    if(len >= col) {
        contents.x = col;
        contents.waiting_for_desired = false;
    } else {
        show_message((std::string("Can't move to column: ")
                      + int_to_str(col)).c_str());
    }
    redrawyx(contents);
}

void mvsot(contents& contents) {
    mvsol(contents);
    const std::string& str = (*contents.cont)[contents.y];
    for(unsigned int i = 0; i < str.length(); i++)
        if(str[i] == ' ' || str[i] == '\t') mvf(contents);
        else break;
}

void mveol(contents& contents) {
    mvcol(contents,(*contents.cont)[contents.y].length() - 1);
}
void mvsol(contents& contents) { mvcol(contents,0); }

void mvsop(contents& contents) {
    contents.y = 0;
    contents.x = 0;
    contents.waiting_for_desired = false;
    redrawyx(contents);
}
void mveop(contents& contents) {
    contents.y = contents.cont->size();
    contents.x = 0;
    contents.waiting_for_desired = false;
    redrawyx(contents);
}

void mvd(contents& contents, long times) {
    if(contents.y + times < 0 || contents.y + times >= contents.cont->size()) {
        show_message("Can't move to that location (start/end of buffer)");
        return;
    }
    int vis = to_visual((*contents.cont)[contents.y],contents.x);
    contents.y += times;
    unsigned int len = (*contents.cont)[contents.y].length();
    if(contents.waiting_for_desired) {
        if(contents.x >= len) {
            contents.x = len - 1;
        } else if(contents.desired_x > contents.x
                  && contents.desired_x < len) {
            // x  desired  len
            contents.x = contents.desired_x;
            contents.waiting_for_desired = false;
        } else {
            // x  len  desired
            contents.x = len - 1;
        }
    } else if(len <= contents.x) {
        contents.waiting_for_desired = true;
        contents.desired_x = contents.x;
        contents.x = len - 1;
    } else {
        //visually adjust x
        //int vis = to_visual((*contents.cont)[contents.y],contents.x);
        contents.x = from_visual((*contents.cont)[contents.y],vis);
    }
    contents.x = contents.x >= 0 ? contents.x : 0;
    redrawyx(contents);
}
void mvu(contents& contents, long times) { mvd(contents,-times); }

static bool isDeliminator(char ch) {
    for(unsigned int i = 0; i < DELIMINATORS().length(); i++)
        if(DELIMINATORS()[i] == ch) return true;
    return false;
}
void mvfw(contents& contents,unsigned long words) {
}
void mvbw(contents& contents,unsigned long words) {
}

inline static unsigned int fixLen(unsigned int len) {
    return len ? len : 1;
}
void mvf(contents& contents, unsigned long times) {
    long newx = contents.x + times;
    try {
        while(fixLen(contents.cont->at(contents.y).length()) <= newx) {
            newx -= fixLen((*contents.cont)[contents.y].length());
            contents.y++;
        }
    } catch(...) { }
    if(contents.y >= contents.cont->size()) contents.y = contents.cont->size()-1;
    if(contents.x < 0) contents.x = 0;
    else      contents.x = newx;
    show_message((std::string("for (x,y): (") + int_to_str(contents.x)
                  + "," + int_to_str(contents.y) + ")").c_str());
    contents.waiting_for_desired = false;
    redrawyx(contents);
}
void mvb(contents& contents, unsigned long times) {
    long newx = contents.x - times;
    while(newx < 0) {
        try {
            contents.y--;
            newx += fixLen(contents.cont->at(contents.y).length());
        } catch(...) {
            break;
        }
    }
    if(contents.y < 0) contents.y = 0;
    if(contents.x < 0) contents.x = 0;
    else      contents.x = newx;
    show_message((std::string("back (x,y): (") + int_to_str(contents.x)
                  + "," + int_to_str(contents.y) + ")").c_str());
    contents.waiting_for_desired = false;
    redrawyx(contents);
}
<commit_msg>Fixed ``mvd''<commit_after>#include <ncurses.h>
#include <string>
#include <vector>

#include "configuration.hh"
#include "int_to_str.hh"
#include "newmove.hh"
#include "show_message.hh"

int from_visual(const std::string& cont, int x) {
    if(cont.size() == 0) return 0;
    int count = 0,
        til = 0;
    for(int i = 0; i < cont.length(); i++) {
        int len;
        if(cont[i] == '\t') {
            len = TAB_SIZE() - 1 - til;
            til = 0;
        } else {
            len = 1;
            til++;
            til %= TAB_SIZE();
        }
        count += len;
        if(count >= x) {
            return i;
        }
    }
}

int to_visual(const std::string& cont, int x) {
    int til = 0,
        xx = -1;
    for(std::string::const_iterator i = cont.begin();
                i <= cont.begin() + x; i++) {
        if(*i == '\t') {
            xx += TAB_SIZE() - til;
            til = 0;
        } else {
            til++;
            til %= TAB_SIZE();
            xx++;
        }
    }
    return xx;
}

void redrawyx(contents& contents) {
    move(contents.y,to_visual((*contents.cont)[contents.y],contents.x));
}

void mvline(contents& contents, unsigned long line) {
    mvrel(contents, line - contents.y, 0);
}
void mv(contents& contents, unsigned long _y, unsigned long _x) {
    mvrel(contents, _y - contents.y, _x - contents.x);
}

void mvrel(contents& contents, long y, long x) {
    if(y < 0) mvu(contents,-y);
    else      mvd(contents, y);
    if(x < 0) mvb(contents,-x);
    else      mvf(contents, x);
}

void mvcol(contents& contents, unsigned long col) {
    unsigned int len = (*contents.cont)[contents.y].length();
    if(len >= col) {
        contents.x = col;
        contents.waiting_for_desired = false;
    } else {
        show_message((std::string("Can't move to column: ")
                      + int_to_str(col)).c_str());
    }
    redrawyx(contents);
}

void mvsot(contents& contents) {
    mvsol(contents);
    const std::string& str = (*contents.cont)[contents.y];
    for(unsigned int i = 0; i < str.length(); i++)
        if(str[i] == ' ' || str[i] == '\t') mvf(contents);
        else break;
}

void mveol(contents& contents) {
    mvcol(contents,(*contents.cont)[contents.y].length() - 1);
}
void mvsol(contents& contents) { mvcol(contents,0); }

void mvsop(contents& contents) {
    contents.y = 0;
    contents.x = 0;
    contents.waiting_for_desired = false;
    redrawyx(contents);
}
void mveop(contents& contents) {
    contents.y = contents.cont->size();
    contents.x = 0;
    contents.waiting_for_desired = false;
    redrawyx(contents);
}

void mvd(contents& contents, long times) {
    if(contents.y + times < 0 || contents.y + times >= contents.cont->size()) {
        show_message("Can't move to that location (start/end of buffer)");
        return;
    }
    int vis = to_visual((*contents.cont)[contents.y],contents.x);
    contents.y += times;
    unsigned int len = (*contents.cont)[contents.y].length();
    if(contents.waiting_for_desired) {
        if(contents.x >= len) {
            contents.x = len - 1;
        } else if(contents.desired_x > contents.x
                  && contents.desired_x < len) {
            // x  desired  len
            contents.x = contents.desired_x;
            contents.waiting_for_desired = false;
        } else {
            // x  len  desired
            contents.x = len - 1;
        }
    } else if(len <= contents.x && len > 0) {
        contents.waiting_for_desired = true;
        contents.desired_x = contents.x;
        contents.x = len - 1;
    } else {
        //visually adjust x
        //int vis = to_visual((*contents.cont)[contents.y],contents.x);
        contents.x = from_visual((*contents.cont)[contents.y],vis);
    }
    contents.x = contents.x >= 0 ? contents.x : 0;
    redrawyx(contents);
}
void mvu(contents& contents, long times) { mvd(contents,-times); }

static bool isDeliminator(char ch) {
    for(unsigned int i = 0; i < DELIMINATORS().length(); i++)
        if(DELIMINATORS()[i] == ch) return true;
    return false;
}
void mvfw(contents& contents,unsigned long words) {
}
void mvbw(contents& contents,unsigned long words) {
}

inline static unsigned int fixLen(unsigned int len) {
    return len ? len : 1;
}
void mvf(contents& contents, unsigned long times) {
    long newx = contents.x + times;
    try {
        while(fixLen(contents.cont->at(contents.y).length()) <= newx) {
            newx -= fixLen((*contents.cont)[contents.y].length());
            contents.y++;
        }
    } catch(...) { }
    if(contents.y >= contents.cont->size()) contents.y = contents.cont->size()-1;
    if(contents.x < 0) contents.x = 0;
    else      contents.x = newx;
    show_message((std::string("for (x,y): (") + int_to_str(contents.x)
                  + "," + int_to_str(contents.y) + ")").c_str());
    contents.waiting_for_desired = false;
    redrawyx(contents);
}
void mvb(contents& contents, unsigned long times) {
    long newx = contents.x - times;
    while(newx < 0) {
        try {
            contents.y--;
            newx += fixLen(contents.cont->at(contents.y).length());
        } catch(...) {
            break;
        }
    }
    if(contents.y < 0) contents.y = 0;
    if(contents.x < 0) contents.x = 0;
    else      contents.x = newx;
    show_message((std::string("back (x,y): (") + int_to_str(contents.x)
                  + "," + int_to_str(contents.y) + ")").c_str());
    contents.waiting_for_desired = false;
    redrawyx(contents);
}
<|endoftext|>


<commit_before>#include "Thief.h"

Thief::Thief()
{
	//Empty
}

Thief::~Thief()
{
	//Empty
}
<commit_msg>Fixed a compiler error by adding implementations for the update function of the Thief class<commit_after>#include "Thief.h"

Thief::Thief()
{
	//Empty
}

Thief::~Thief()
{
	//Empty
}

void Thief::update(const std::vector<std::string>& WorldData) {

}

void Thief::update() {

}<|endoftext|>


<commit_before>//
//  kern_cpuf.cpp
//  CPUFriend
//
//  Copyright © 2017 Vanilla. All rights reserved.
//

#include <Headers/kern_api.hpp>
#include "kern_cpuf.hpp"

static const char *binList[] {
  "/System/Library/Extensions/IOPlatformPluginFamily.kext/Contents/PlugIns/X86PlatformPlugin.kext/Contents/MacOS/X86PlatformPlugin"
};

static const char *idList[] {
  "com.apple.driver.X86PlatformPlugin"
};

static const char *symbolList[] {
  "__ZN17X86PlatformPlugin22configResourceCallbackEjiPKvjPv"
};

static KernelPatcher::KextInfo kextList[] {
  { idList[0], &binList[0], arrsize(binList), false, false, {}, KernelPatcher::KextInfo::Unloaded }
};

static constexpr size_t kextListSize {arrsize(kextList)};

static CPUFriendPlugin *callbackCpuf {nullptr};

OSDefineMetaClassAndStructors(CPUFriendPlatform, IOService)

IOService *CPUFriendPlatform::probe(IOService *provider, SInt32 *score) {
  if (provider) {
    if (callbackCpuf) {
      if (!callbackCpuf->frequencyData) {
        auto name = provider->getName();
        if (!name)
          name = "(null)";
        DBGLOG("cpuf @ looking for cf-frequency-data in %s", name);

        auto data = OSDynamicCast(OSData, provider->getProperty("cf-frequency-data"));
        if (!data) {
          auto cpu = provider->getParentEntry(gIOServicePlane);
          if (cpu) {
            name = cpu->getName();
            if (!name)
              name = "(null)";
            DBGLOG("cpuf @ looking for cf-frequency-data in %s", name);

            data = OSDynamicCast(OSData, cpu->getProperty("cf-frequency-data"));
          } else {
            SYSLOG("cpuf @ unable to access cpu parent");
          }
        }

        if (data) {
          callbackCpuf->frequencyDataSize = data->getLength();
          callbackCpuf->frequencyData = data->getBytesNoCopy();
        } else {
          SYSLOG("cpuf @ failed to obtain cf-frequency-data");
        }
      }
    } else {
      SYSLOG("cpuf @ missing storage instance");
    }
  }

  return nullptr;
}

bool CPUFriendPlugin::init() {
  callbackCpuf = this;

  LiluAPI::Error error = lilu.onKextLoad(kextList, kextListSize,
  [](void *user, KernelPatcher &patcher, size_t index, mach_vm_address_t address, size_t size) {
    static_cast<CPUFriendPlugin *>(user)->processKext(patcher, index, address, size);
  }, this);

  if (error != LiluAPI::Error::NoError) {
    SYSLOG("cpuf @ failed to register onKextLoad method %d", error);
    return false;
  }

  return true;
}

void CPUFriendPlugin::myConfigResourceCallback(uint32_t requestTag, kern_return_t result, const void *resourceData, uint32_t resourceDataLength, void *context) {
  if (callbackCpuf && callbackCpuf->orgConfigLoadCallback) {
    auto data = callbackCpuf->frequencyData;
    auto sz = callbackCpuf->frequencyDataSize;
    if (data && sz > 0) {
      DBGLOG("cpuf @ feeding frequency data %u", sz);
      resourceData = data;
      resourceDataLength = sz;
      result = kOSReturnSuccess;
    } else {
      SYSLOG("cpuf @ failed to feed cpu data (%u, %d)", sz, data != nullptr);
    }

    callbackCpuf->orgConfigLoadCallback(requestTag, result, resourceData, resourceDataLength, context);
  } else {
    SYSLOG("cpuf @ config callback arrived at nowhere");
  }
}

void CPUFriendPlugin::processKext(KernelPatcher &patcher, size_t index, mach_vm_address_t address, size_t size) {
  if (progressState != cpufessingState::EverythingDone) {
    for (size_t i = 0; i < kextListSize; i++) {
      if (kextList[i].loadIndex == index) {
        DBGLOG("cpuf @ current kext is %s progressState %d", kextList[i].id, progressState);

        if (!strcmp(kextList[i].id, idList[0])) {
          auto callback = patcher.solveSymbol(index, symbolList[0]);
          if (callback) {
            orgConfigLoadCallback = reinterpret_cast<t_callback>(patcher.routeFunction(callback, reinterpret_cast<mach_vm_address_t>(myConfigResourceCallback), true));
            if (patcher.getError() == KernelPatcher::Error::NoError) {
              DBGLOG("cpuf @ routed %s", symbolList[0]);
            } else {
              SYSLOG("cpuf @ failed to route %s", symbolList[0]);
            }
          } else {
            SYSLOG("cpuf @ failed to find %s", symbolList[0]);
          }

          progressState |= cpufessingState::CallbackRouted;
        }

        // Ignore all the errors for other processors
        patcher.clearError();
        break;
      }
    }
  }
}
<commit_msg>Fixed compatibility with recent Lilu changes<commit_after>//
//  kern_cpuf.cpp
//  CPUFriend
//
//  Copyright © 2017 Vanilla. All rights reserved.
//

#include <Headers/kern_api.hpp>
#include "kern_cpuf.hpp"

static const char *binList[] {
  "/System/Library/Extensions/IOPlatformPluginFamily.kext/Contents/PlugIns/X86PlatformPlugin.kext/Contents/MacOS/X86PlatformPlugin"
};

static const char *idList[] {
  "com.apple.driver.X86PlatformPlugin"
};

static const char *symbolList[] {
  "__ZN17X86PlatformPlugin22configResourceCallbackEjiPKvjPv"
};

static KernelPatcher::KextInfo kextList[] {
  { idList[0], &binList[0], arrsize(binList), {false, false}, {}, KernelPatcher::KextInfo::Unloaded }
};

static constexpr size_t kextListSize {arrsize(kextList)};

static CPUFriendPlugin *callbackCpuf {nullptr};

OSDefineMetaClassAndStructors(CPUFriendPlatform, IOService)

IOService *CPUFriendPlatform::probe(IOService *provider, SInt32 *score) {
  if (provider) {
    if (callbackCpuf) {
      if (!callbackCpuf->frequencyData) {
        auto name = provider->getName();
        if (!name)
          name = "(null)";
        DBGLOG("cpuf @ looking for cf-frequency-data in %s", name);

        auto data = OSDynamicCast(OSData, provider->getProperty("cf-frequency-data"));
        if (!data) {
          auto cpu = provider->getParentEntry(gIOServicePlane);
          if (cpu) {
            name = cpu->getName();
            if (!name)
              name = "(null)";
            DBGLOG("cpuf @ looking for cf-frequency-data in %s", name);

            data = OSDynamicCast(OSData, cpu->getProperty("cf-frequency-data"));
          } else {
            SYSLOG("cpuf @ unable to access cpu parent");
          }
        }

        if (data) {
          callbackCpuf->frequencyDataSize = data->getLength();
          callbackCpuf->frequencyData = data->getBytesNoCopy();
        } else {
          SYSLOG("cpuf @ failed to obtain cf-frequency-data");
        }
      }
    } else {
      SYSLOG("cpuf @ missing storage instance");
    }
  }

  return nullptr;
}

bool CPUFriendPlugin::init() {
  callbackCpuf = this;

  LiluAPI::Error error = lilu.onKextLoad(kextList, kextListSize,
  [](void *user, KernelPatcher &patcher, size_t index, mach_vm_address_t address, size_t size) {
    static_cast<CPUFriendPlugin *>(user)->processKext(patcher, index, address, size);
  }, this);

  if (error != LiluAPI::Error::NoError) {
    SYSLOG("cpuf @ failed to register onKextLoad method %d", error);
    return false;
  }

  return true;
}

void CPUFriendPlugin::myConfigResourceCallback(uint32_t requestTag, kern_return_t result, const void *resourceData, uint32_t resourceDataLength, void *context) {
  if (callbackCpuf && callbackCpuf->orgConfigLoadCallback) {
    auto data = callbackCpuf->frequencyData;
    auto sz = callbackCpuf->frequencyDataSize;
    if (data && sz > 0) {
      DBGLOG("cpuf @ feeding frequency data %u", sz);
      resourceData = data;
      resourceDataLength = sz;
      result = kOSReturnSuccess;
    } else {
      SYSLOG("cpuf @ failed to feed cpu data (%u, %d)", sz, data != nullptr);
    }

    callbackCpuf->orgConfigLoadCallback(requestTag, result, resourceData, resourceDataLength, context);
  } else {
    SYSLOG("cpuf @ config callback arrived at nowhere");
  }
}

void CPUFriendPlugin::processKext(KernelPatcher &patcher, size_t index, mach_vm_address_t address, size_t size) {
  if (progressState != cpufessingState::EverythingDone) {
    for (size_t i = 0; i < kextListSize; i++) {
      if (kextList[i].loadIndex == index) {
        DBGLOG("cpuf @ current kext is %s progressState %d", kextList[i].id, progressState);

        if (!strcmp(kextList[i].id, idList[0])) {
          auto callback = patcher.solveSymbol(index, symbolList[0]);
          if (callback) {
            orgConfigLoadCallback = reinterpret_cast<t_callback>(patcher.routeFunction(callback, reinterpret_cast<mach_vm_address_t>(myConfigResourceCallback), true));
            if (patcher.getError() == KernelPatcher::Error::NoError) {
              DBGLOG("cpuf @ routed %s", symbolList[0]);
            } else {
              SYSLOG("cpuf @ failed to route %s", symbolList[0]);
            }
          } else {
            SYSLOG("cpuf @ failed to find %s", symbolList[0]);
          }

          progressState |= cpufessingState::CallbackRouted;
        }

        // Ignore all the errors for other processors
        patcher.clearError();
        break;
      }
    }
  }
}
<|endoftext|>