<commit_before>//===--- RawSyntax.cpp - Swift Raw Syntax Implementation ------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "swift/Basic/ColorUtils.h"
#include "swift/Syntax/RawSyntax.h"
#include "swift/Syntax/SyntaxArena.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/raw_ostream.h"

#include <algorithm>

using llvm::dyn_cast;
using namespace swift;
using namespace swift::syntax;

namespace {
static bool isTrivialSyntaxKind(SyntaxKind Kind) {
  if (isUnknownKind(Kind))
    return true;
  if (isCollectionKind(Kind))
    return true;
  switch(Kind) {
  case SyntaxKind::SourceFile:
  case SyntaxKind::CodeBlockItem:
  case SyntaxKind::ExpressionStmt:
  case SyntaxKind::DeclarationStmt:
    return true;
  default:
    return false;
  }
}

static void printSyntaxKind(SyntaxKind Kind, llvm::raw_ostream &OS,
                            SyntaxPrintOptions Opts, bool Open) {
  std::unique_ptr<swift::OSColor> Color;
  if (Opts.Visual) {
    Color.reset(new swift::OSColor(OS, llvm::raw_ostream::GREEN));
  }
  OS << "<";
  if (!Open)
    OS << "/";
  dumpSyntaxKind(OS, Kind);
  OS << ">";
}

} // end of anonymous namespace

void swift::dumpTokenKind(llvm::raw_ostream &OS, tok Kind) {
  switch (Kind) {
#define TOKEN(X)                                                               \
  case tok::X:                                                                 \
    OS << #X;                                                                  \
    break;
#include "swift/Syntax/TokenKinds.def"
  case tok::NUM_TOKENS:
    OS << "NUM_TOKENS (unset)";
    break;
  }
}

unsigned RawSyntax::NextFreeNodeId = 1;

RawSyntax::RawSyntax(SyntaxKind Kind, ArrayRef<RC<RawSyntax>> Layout,
                     SourcePresence Presence, const RC<SyntaxArena> &Arena,
                     llvm::Optional<unsigned> NodeId) {
  assert(Kind != SyntaxKind::Token &&
         "'token' syntax node must be constructed with dedicated constructor");

  RefCount = 0;

  if (NodeId.hasValue()) {
    this->NodeId = NodeId.getValue();
    NextFreeNodeId = std::max(this->NodeId + 1, NextFreeNodeId);
  } else {
    this->NodeId = NextFreeNodeId++;
  }
  Bits.Common.Kind = unsigned(Kind);
  Bits.Common.Presence = unsigned(Presence);
  Bits.Layout.NumChildren = Layout.size();
  Bits.Layout.TextLength = UINT32_MAX;

  this->Arena = Arena;

  // Initialize layout data.
  std::uninitialized_copy(Layout.begin(), Layout.end(),
                          getTrailingObjects<RC<RawSyntax>>());
}

RawSyntax::RawSyntax(tok TokKind, OwnedString Text,
                     ArrayRef<TriviaPiece> LeadingTrivia,
                     ArrayRef<TriviaPiece> TrailingTrivia,
                     SourcePresence Presence, const RC<SyntaxArena> &Arena,
                     llvm::Optional<unsigned> NodeId) {
  RefCount = 0;

  if (NodeId.hasValue()) {
    this->NodeId = NodeId.getValue();
    NextFreeNodeId = std::max(this->NodeId + 1, NextFreeNodeId);
  } else {
    this->NodeId = NextFreeNodeId++;
  }
  Bits.Common.Kind = unsigned(SyntaxKind::Token);
  Bits.Common.Presence = unsigned(Presence);
  Bits.Token.TokenKind = unsigned(TokKind);
  Bits.Token.NumLeadingTrivia = LeadingTrivia.size();
  Bits.Token.NumTrailingTrivia = TrailingTrivia.size();

  this->Arena = Arena;

  // Initialize token text.
  ::new (static_cast<void *>(getTrailingObjects<OwnedString>()))
      OwnedString(Text);
  // Initialize leading trivia.
  std::uninitialized_copy(LeadingTrivia.begin(), LeadingTrivia.end(),
                          getTrailingObjects<TriviaPiece>());
  // Initialize trailing trivia.
  std::uninitialized_copy(TrailingTrivia.begin(), TrailingTrivia.end(),
                          getTrailingObjects<TriviaPiece>() +
                              Bits.Token.NumLeadingTrivia);
}

RawSyntax::~RawSyntax() {
  if (isToken()) {
    getTrailingObjects<OwnedString>()->~OwnedString();
    for (auto &trivia : getLeadingTrivia())
      trivia.~TriviaPiece();
    for (auto &trivia : getTrailingTrivia())
      trivia.~TriviaPiece();
  } else {
    for (auto &child : getLayout())
      child.~RC<RawSyntax>();
  }
}

RC<RawSyntax> RawSyntax::make(SyntaxKind Kind, ArrayRef<RC<RawSyntax>> Layout,
                              SourcePresence Presence,
                              const RC<SyntaxArena> &Arena,
                              llvm::Optional<unsigned> NodeId) {
  auto size = totalSizeToAlloc<RC<RawSyntax>, OwnedString, TriviaPiece>(
      Layout.size(), 0, 0);
  void *data = Arena ? Arena->Allocate(size, alignof(RawSyntax))
                     : ::operator new(size);
  return RC<RawSyntax>(
      new (data) RawSyntax(Kind, Layout, Presence, Arena, NodeId));
}

RC<RawSyntax> RawSyntax::make(tok TokKind, OwnedString Text,
                              ArrayRef<TriviaPiece> LeadingTrivia,
                              ArrayRef<TriviaPiece> TrailingTrivia,
                              SourcePresence Presence,
                              const RC<SyntaxArena> &Arena,
                              llvm::Optional<unsigned> NodeId) {
  auto size = totalSizeToAlloc<RC<RawSyntax>, OwnedString, TriviaPiece>(
      0, 1, LeadingTrivia.size() + TrailingTrivia.size());
  void *data = Arena ? Arena->Allocate(size, alignof(RawSyntax))
                     : ::operator new(size);
  return RC<RawSyntax>(new (data) RawSyntax(TokKind, Text, LeadingTrivia,
                                            TrailingTrivia, Presence,
                                            Arena, NodeId));
}

RC<RawSyntax> RawSyntax::append(RC<RawSyntax> NewLayoutElement) const {
  auto Layout = getLayout();
  std::vector<RC<RawSyntax>> NewLayout;
  NewLayout.reserve(Layout.size() + 1);
  std::copy(Layout.begin(), Layout.end(), std::back_inserter(NewLayout));
  NewLayout.push_back(NewLayoutElement);
  return RawSyntax::make(getKind(), NewLayout, SourcePresence::Present);
}

RC<RawSyntax> RawSyntax::replaceChild(CursorIndex Index,
                                      RC<RawSyntax> NewLayoutElement) const {
  auto Layout = getLayout();
  std::vector<RC<RawSyntax>> NewLayout;
  NewLayout.reserve(Layout.size());

  std::copy(Layout.begin(), Layout.begin() + Index,
            std::back_inserter(NewLayout));

  NewLayout.push_back(NewLayoutElement);

  std::copy(Layout.begin() + Index + 1, Layout.end(),
            std::back_inserter(NewLayout));

  return RawSyntax::make(getKind(), NewLayout, getPresence());
}

llvm::Optional<AbsolutePosition>
RawSyntax::accumulateAbsolutePosition(AbsolutePosition &Pos) const {
  llvm::Optional<AbsolutePosition> Ret;
  if (isToken()) {
    if (isMissing())
      return None;
    for (auto &Leader : getLeadingTrivia())
      Leader.accumulateAbsolutePosition(Pos);
    Ret = Pos;
    Pos.addText(getTokenText());
    for (auto &Trailer : getTrailingTrivia())
      Trailer.accumulateAbsolutePosition(Pos);
  } else {
    for (auto &Child : getLayout()) {
      if (!Child)
        continue;
      auto Result = Child->accumulateAbsolutePosition(Pos);
      if (!Ret && Result)
        Ret = Result;
    }
  }
  return Ret;
}

bool RawSyntax::accumulateLeadingTrivia(AbsolutePosition &Pos) const {
 if (isToken()) {
    if (!isMissing()) {
      for (auto &Leader: getLeadingTrivia())
        Leader.accumulateAbsolutePosition(Pos);
      return true;
    }
  } else {
    for (auto &Child: getLayout()) {
      if (!Child || Child->isMissing())
        continue;
      if (Child->accumulateLeadingTrivia(Pos))
        return true;
    }
  }
  return false;
}

void RawSyntax::print(llvm::raw_ostream &OS, SyntaxPrintOptions Opts) const {
  if (isMissing())
    return;

  if (isToken()) {
    for (const auto &Leader : getLeadingTrivia())
      Leader.print(OS);

    OS << getTokenText();

    for (const auto &Trailer : getTrailingTrivia())
      Trailer.print(OS);
  } else {
    auto Kind = getKind();
    const bool PrintKind = Opts.PrintSyntaxKind && (Opts.PrintTrivialNodeKind ||
                                                    !isTrivialSyntaxKind(Kind));
    if (PrintKind)
      printSyntaxKind(Kind, OS, Opts, true);

    for (const auto &LE : getLayout())
      if (LE)
        LE->print(OS, Opts);

    if (PrintKind)
      printSyntaxKind(Kind, OS, Opts, false);
  }
}

void RawSyntax::dump() const {
  dump(llvm::errs(), /*Indent*/ 0);
  llvm::errs() << '\n';
}

void RawSyntax::dump(llvm::raw_ostream &OS, unsigned Indent) const {
  auto indent = [&](unsigned Amount) {
    for (decltype(Amount) i = 0; i < Amount; ++i) {
      OS << ' ';
    }
  };

  indent(Indent);
  OS << '(';
  dumpSyntaxKind(OS, getKind());

  if (isMissing())
    OS << " [missing] ";

  if (isToken()) {
    OS << " ";
    dumpTokenKind(OS, getTokenKind());

    for (auto &Leader : getLeadingTrivia()) {
      OS << "\n";
      Leader.dump(OS, Indent + 1);
    }

    OS << "\n";
    indent(Indent + 1);
    OS << "(text=\"";
    OS.write_escaped(getTokenText(), /*UseHexEscapes=*/true);
    OS << "\")";

    for (auto &Trailer : getTrailingTrivia()) {
      OS << "\n";
      Trailer.dump(OS, Indent + 1);
    }
  } else {
    for (auto &Child : getLayout()) {
      if (!Child)
        continue;
      OS << "\n";
      Child->dump(OS, Indent + 1);
    }
  }
  OS << ')';
}

void AbsolutePosition::printLineAndColumn(llvm::raw_ostream &OS) const {
  OS << getLine() << ':' << getColumn();
}

void AbsolutePosition::dump(llvm::raw_ostream &OS) const {
  OS << "(absolute_position ";
  OS << "offset=" << getOffset() << " ";
  OS << "line=" << getLine() << " ";
  OS << "column=" << getColumn();
  OS << ')';
}

void RawSyntax::Profile(llvm::FoldingSetNodeID &ID, tok TokKind,
                        OwnedString Text, ArrayRef<TriviaPiece> LeadingTrivia,
                        ArrayRef<TriviaPiece> TrailingTrivia) {
  ID.AddInteger(unsigned(TokKind));
  switch (TokKind) {
#define TOKEN_DEFAULT(NAME) case tok::NAME:
#define PUNCTUATOR(NAME, X) TOKEN_DEFAULT(NAME)
#define KEYWORD(KW) TOKEN_DEFAULT(kw_##KW)
#define POUND_KEYWORD(KW) TOKEN_DEFAULT(pound_##KW)
#include "swift/Syntax/TokenKinds.def"
    break;
  default:
    ID.AddString(Text.str());
    break;
  }
  for (auto &Piece : LeadingTrivia)
    Piece.Profile(ID);
  for (auto &Piece : TrailingTrivia)
    Piece.Profile(ID);
}

llvm::raw_ostream &llvm::operator<<(raw_ostream &OS, AbsolutePosition Pos) {
  Pos.printLineAndColumn(OS);
  return OS;
}
<commit_msg>[Syntax] Include leading/trailing trivia size to the cache ID<commit_after>//===--- RawSyntax.cpp - Swift Raw Syntax Implementation ------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "swift/Basic/ColorUtils.h"
#include "swift/Syntax/RawSyntax.h"
#include "swift/Syntax/SyntaxArena.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/raw_ostream.h"

#include <algorithm>

using llvm::dyn_cast;
using namespace swift;
using namespace swift::syntax;

namespace {
static bool isTrivialSyntaxKind(SyntaxKind Kind) {
  if (isUnknownKind(Kind))
    return true;
  if (isCollectionKind(Kind))
    return true;
  switch(Kind) {
  case SyntaxKind::SourceFile:
  case SyntaxKind::CodeBlockItem:
  case SyntaxKind::ExpressionStmt:
  case SyntaxKind::DeclarationStmt:
    return true;
  default:
    return false;
  }
}

static void printSyntaxKind(SyntaxKind Kind, llvm::raw_ostream &OS,
                            SyntaxPrintOptions Opts, bool Open) {
  std::unique_ptr<swift::OSColor> Color;
  if (Opts.Visual) {
    Color.reset(new swift::OSColor(OS, llvm::raw_ostream::GREEN));
  }
  OS << "<";
  if (!Open)
    OS << "/";
  dumpSyntaxKind(OS, Kind);
  OS << ">";
}

} // end of anonymous namespace

void swift::dumpTokenKind(llvm::raw_ostream &OS, tok Kind) {
  switch (Kind) {
#define TOKEN(X)                                                               \
  case tok::X:                                                                 \
    OS << #X;                                                                  \
    break;
#include "swift/Syntax/TokenKinds.def"
  case tok::NUM_TOKENS:
    OS << "NUM_TOKENS (unset)";
    break;
  }
}

unsigned RawSyntax::NextFreeNodeId = 1;

RawSyntax::RawSyntax(SyntaxKind Kind, ArrayRef<RC<RawSyntax>> Layout,
                     SourcePresence Presence, const RC<SyntaxArena> &Arena,
                     llvm::Optional<unsigned> NodeId) {
  assert(Kind != SyntaxKind::Token &&
         "'token' syntax node must be constructed with dedicated constructor");

  RefCount = 0;

  if (NodeId.hasValue()) {
    this->NodeId = NodeId.getValue();
    NextFreeNodeId = std::max(this->NodeId + 1, NextFreeNodeId);
  } else {
    this->NodeId = NextFreeNodeId++;
  }
  Bits.Common.Kind = unsigned(Kind);
  Bits.Common.Presence = unsigned(Presence);
  Bits.Layout.NumChildren = Layout.size();
  Bits.Layout.TextLength = UINT32_MAX;

  this->Arena = Arena;

  // Initialize layout data.
  std::uninitialized_copy(Layout.begin(), Layout.end(),
                          getTrailingObjects<RC<RawSyntax>>());
}

RawSyntax::RawSyntax(tok TokKind, OwnedString Text,
                     ArrayRef<TriviaPiece> LeadingTrivia,
                     ArrayRef<TriviaPiece> TrailingTrivia,
                     SourcePresence Presence, const RC<SyntaxArena> &Arena,
                     llvm::Optional<unsigned> NodeId) {
  RefCount = 0;

  if (NodeId.hasValue()) {
    this->NodeId = NodeId.getValue();
    NextFreeNodeId = std::max(this->NodeId + 1, NextFreeNodeId);
  } else {
    this->NodeId = NextFreeNodeId++;
  }
  Bits.Common.Kind = unsigned(SyntaxKind::Token);
  Bits.Common.Presence = unsigned(Presence);
  Bits.Token.TokenKind = unsigned(TokKind);
  Bits.Token.NumLeadingTrivia = LeadingTrivia.size();
  Bits.Token.NumTrailingTrivia = TrailingTrivia.size();

  this->Arena = Arena;

  // Initialize token text.
  ::new (static_cast<void *>(getTrailingObjects<OwnedString>()))
      OwnedString(Text);
  // Initialize leading trivia.
  std::uninitialized_copy(LeadingTrivia.begin(), LeadingTrivia.end(),
                          getTrailingObjects<TriviaPiece>());
  // Initialize trailing trivia.
  std::uninitialized_copy(TrailingTrivia.begin(), TrailingTrivia.end(),
                          getTrailingObjects<TriviaPiece>() +
                              Bits.Token.NumLeadingTrivia);
}

RawSyntax::~RawSyntax() {
  if (isToken()) {
    getTrailingObjects<OwnedString>()->~OwnedString();
    for (auto &trivia : getLeadingTrivia())
      trivia.~TriviaPiece();
    for (auto &trivia : getTrailingTrivia())
      trivia.~TriviaPiece();
  } else {
    for (auto &child : getLayout())
      child.~RC<RawSyntax>();
  }
}

RC<RawSyntax> RawSyntax::make(SyntaxKind Kind, ArrayRef<RC<RawSyntax>> Layout,
                              SourcePresence Presence,
                              const RC<SyntaxArena> &Arena,
                              llvm::Optional<unsigned> NodeId) {
  auto size = totalSizeToAlloc<RC<RawSyntax>, OwnedString, TriviaPiece>(
      Layout.size(), 0, 0);
  void *data = Arena ? Arena->Allocate(size, alignof(RawSyntax))
                     : ::operator new(size);
  return RC<RawSyntax>(
      new (data) RawSyntax(Kind, Layout, Presence, Arena, NodeId));
}

RC<RawSyntax> RawSyntax::make(tok TokKind, OwnedString Text,
                              ArrayRef<TriviaPiece> LeadingTrivia,
                              ArrayRef<TriviaPiece> TrailingTrivia,
                              SourcePresence Presence,
                              const RC<SyntaxArena> &Arena,
                              llvm::Optional<unsigned> NodeId) {
  auto size = totalSizeToAlloc<RC<RawSyntax>, OwnedString, TriviaPiece>(
      0, 1, LeadingTrivia.size() + TrailingTrivia.size());
  void *data = Arena ? Arena->Allocate(size, alignof(RawSyntax))
                     : ::operator new(size);
  return RC<RawSyntax>(new (data) RawSyntax(TokKind, Text, LeadingTrivia,
                                            TrailingTrivia, Presence,
                                            Arena, NodeId));
}

RC<RawSyntax> RawSyntax::append(RC<RawSyntax> NewLayoutElement) const {
  auto Layout = getLayout();
  std::vector<RC<RawSyntax>> NewLayout;
  NewLayout.reserve(Layout.size() + 1);
  std::copy(Layout.begin(), Layout.end(), std::back_inserter(NewLayout));
  NewLayout.push_back(NewLayoutElement);
  return RawSyntax::make(getKind(), NewLayout, SourcePresence::Present);
}

RC<RawSyntax> RawSyntax::replaceChild(CursorIndex Index,
                                      RC<RawSyntax> NewLayoutElement) const {
  auto Layout = getLayout();
  std::vector<RC<RawSyntax>> NewLayout;
  NewLayout.reserve(Layout.size());

  std::copy(Layout.begin(), Layout.begin() + Index,
            std::back_inserter(NewLayout));

  NewLayout.push_back(NewLayoutElement);

  std::copy(Layout.begin() + Index + 1, Layout.end(),
            std::back_inserter(NewLayout));

  return RawSyntax::make(getKind(), NewLayout, getPresence());
}

llvm::Optional<AbsolutePosition>
RawSyntax::accumulateAbsolutePosition(AbsolutePosition &Pos) const {
  llvm::Optional<AbsolutePosition> Ret;
  if (isToken()) {
    if (isMissing())
      return None;
    for (auto &Leader : getLeadingTrivia())
      Leader.accumulateAbsolutePosition(Pos);
    Ret = Pos;
    Pos.addText(getTokenText());
    for (auto &Trailer : getTrailingTrivia())
      Trailer.accumulateAbsolutePosition(Pos);
  } else {
    for (auto &Child : getLayout()) {
      if (!Child)
        continue;
      auto Result = Child->accumulateAbsolutePosition(Pos);
      if (!Ret && Result)
        Ret = Result;
    }
  }
  return Ret;
}

bool RawSyntax::accumulateLeadingTrivia(AbsolutePosition &Pos) const {
 if (isToken()) {
    if (!isMissing()) {
      for (auto &Leader: getLeadingTrivia())
        Leader.accumulateAbsolutePosition(Pos);
      return true;
    }
  } else {
    for (auto &Child: getLayout()) {
      if (!Child || Child->isMissing())
        continue;
      if (Child->accumulateLeadingTrivia(Pos))
        return true;
    }
  }
  return false;
}

void RawSyntax::print(llvm::raw_ostream &OS, SyntaxPrintOptions Opts) const {
  if (isMissing())
    return;

  if (isToken()) {
    for (const auto &Leader : getLeadingTrivia())
      Leader.print(OS);

    OS << getTokenText();

    for (const auto &Trailer : getTrailingTrivia())
      Trailer.print(OS);
  } else {
    auto Kind = getKind();
    const bool PrintKind = Opts.PrintSyntaxKind && (Opts.PrintTrivialNodeKind ||
                                                    !isTrivialSyntaxKind(Kind));
    if (PrintKind)
      printSyntaxKind(Kind, OS, Opts, true);

    for (const auto &LE : getLayout())
      if (LE)
        LE->print(OS, Opts);

    if (PrintKind)
      printSyntaxKind(Kind, OS, Opts, false);
  }
}

void RawSyntax::dump() const {
  dump(llvm::errs(), /*Indent*/ 0);
  llvm::errs() << '\n';
}

void RawSyntax::dump(llvm::raw_ostream &OS, unsigned Indent) const {
  auto indent = [&](unsigned Amount) {
    for (decltype(Amount) i = 0; i < Amount; ++i) {
      OS << ' ';
    }
  };

  indent(Indent);
  OS << '(';
  dumpSyntaxKind(OS, getKind());

  if (isMissing())
    OS << " [missing] ";

  if (isToken()) {
    OS << " ";
    dumpTokenKind(OS, getTokenKind());

    for (auto &Leader : getLeadingTrivia()) {
      OS << "\n";
      Leader.dump(OS, Indent + 1);
    }

    OS << "\n";
    indent(Indent + 1);
    OS << "(text=\"";
    OS.write_escaped(getTokenText(), /*UseHexEscapes=*/true);
    OS << "\")";

    for (auto &Trailer : getTrailingTrivia()) {
      OS << "\n";
      Trailer.dump(OS, Indent + 1);
    }
  } else {
    for (auto &Child : getLayout()) {
      if (!Child)
        continue;
      OS << "\n";
      Child->dump(OS, Indent + 1);
    }
  }
  OS << ')';
}

void AbsolutePosition::printLineAndColumn(llvm::raw_ostream &OS) const {
  OS << getLine() << ':' << getColumn();
}

void AbsolutePosition::dump(llvm::raw_ostream &OS) const {
  OS << "(absolute_position ";
  OS << "offset=" << getOffset() << " ";
  OS << "line=" << getLine() << " ";
  OS << "column=" << getColumn();
  OS << ')';
}

void RawSyntax::Profile(llvm::FoldingSetNodeID &ID, tok TokKind,
                        OwnedString Text, ArrayRef<TriviaPiece> LeadingTrivia,
                        ArrayRef<TriviaPiece> TrailingTrivia) {
  ID.AddInteger(unsigned(TokKind));
  ID.AddInteger(LeadingTrivia.size());
  ID.AddInteger(TrailingTrivia.size());
  switch (TokKind) {
#define TOKEN_DEFAULT(NAME) case tok::NAME:
#define PUNCTUATOR(NAME, X) TOKEN_DEFAULT(NAME)
#define KEYWORD(KW) TOKEN_DEFAULT(kw_##KW)
#define POUND_KEYWORD(KW) TOKEN_DEFAULT(pound_##KW)
#include "swift/Syntax/TokenKinds.def"
    break;
  default:
    ID.AddString(Text.str());
    break;
  }
  for (auto &Piece : LeadingTrivia)
    Piece.Profile(ID);
  for (auto &Piece : TrailingTrivia)
    Piece.Profile(ID);
}

llvm::raw_ostream &llvm::operator<<(raw_ostream &OS, AbsolutePosition Pos) {
  Pos.printLineAndColumn(OS);
  return OS;
}
<|endoftext|>


<commit_before>//--------------------------------------------------------------------*- C++ -*-
// CLING - the C++ LLVM-based InterpreterG :)
// author:  Vassil Vassilev <vasil.georgiev.vasilev@cern.ch>
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

#include "cling/Utils/Validation.h"
#include "llvm/Support/ThreadLocal.h"

#include <assert.h>
#include <errno.h>
#ifdef LLVM_ON_WIN32
# include <Windows.h>
#else
#include <array>
#include <algorithm>
#include <fcntl.h>
# include <unistd.h>
#endif

namespace cling {
  namespace utils {

#ifndef LLVM_ON_WIN32
    // A simple round-robin cache: what enters first, leaves first.
    // MRU cache wasn't worth the extra CPU cycles.
    struct Cache {
    private:
      std::array<const void*, 8> lines;
      unsigned mostRecent = 0;
    public:
      bool contains(const void* P) {
        return std::find(lines.begin(), lines.end(), P) != lines.end();
      }
      void push(const void* P) {
        mostRecent = (mostRecent + 1) % lines.size();
        lines[mostRecent] = P;
      }
    };

    // Trying to be thread-safe.
    // Each thread creates a new cache when needed.
    static Cache& getCache() {
      static llvm::sys::ThreadLocal<Cache> threadCache;
      if (!threadCache.get()) {
        // Leak, 1 Cache/thread.
        threadCache.set(new Cache());
      }
      return *threadCache.get();
    }

    static int getNullDevFileDescriptor() {
      struct FileDescriptor {
        int FD;
        const char* file = "/dev/null";
        FileDescriptor() { FD = open(file, O_WRONLY); }
        ~FileDescriptor() {
          close(FD);
        }
      };
      static FileDescriptor nullDev;
      return nullDev.FD;
    }
#endif

    // Checking whether the pointer points to a valid memory location
    bool isAddressValid(const void *P) {
      if (!P || P == (void *) -1)
        return false;

#ifdef LLVM_ON_WIN32
      MEMORY_BASIC_INFORMATION MBI;
      if (!VirtualQuery(P, &MBI, sizeof(MBI)))
        return false;
      if (MBI.State != MEM_COMMIT)
        return false;
      return true;
#else
      // Look-up the address in the cache.
      Cache& currentCache = getCache();
      if (currentCache.contains(P))
        return true;
      // There is a POSIX way of finding whether an address
      // can be accessed for reading.
      if (write(getNullDevFileDescriptor(), P, 1/*byte*/) != 1) {
        assert(errno == EFAULT && "unexpected write error at address");
        return false;
      }
      currentCache.push(P);
      return true;
#endif
    }
  }
}
<commit_msg>Use /dev/random, some kernels skip writing to /dev/null.<commit_after>//--------------------------------------------------------------------*- C++ -*-
// CLING - the C++ LLVM-based InterpreterG :)
// author:  Vassil Vassilev <vasil.georgiev.vasilev@cern.ch>
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

#include "cling/Utils/Validation.h"
#include "llvm/Support/ThreadLocal.h"

#include <assert.h>
#include <errno.h>
#ifdef LLVM_ON_WIN32
# include <Windows.h>
#else
#include <array>
#include <algorithm>
#include <fcntl.h>
# include <unistd.h>
#endif

namespace cling {
  namespace utils {

#ifndef LLVM_ON_WIN32
    // A simple round-robin cache: what enters first, leaves first.
    // MRU cache wasn't worth the extra CPU cycles.
    struct Cache {
    private:
      std::array<const void*, 8> lines;
      unsigned mostRecent = 0;
    public:
      bool contains(const void* P) {
        return std::find(lines.begin(), lines.end(), P) != lines.end();
      }
      void push(const void* P) {
        mostRecent = (mostRecent + 1) % lines.size();
        lines[mostRecent] = P;
      }
    };

    // Trying to be thread-safe.
    // Each thread creates a new cache when needed.
    static Cache& getCache() {
      static llvm::sys::ThreadLocal<Cache> threadCache;
      if (!threadCache.get()) {
        // Leak, 1 Cache/thread.
        threadCache.set(new Cache());
      }
      return *threadCache.get();
    }

    static int getNullDevFileDescriptor() {
      struct FileDescriptor {
        int FD;
        const char* file = "/dev/random";
        FileDescriptor() { FD = open(file, O_WRONLY); }
        ~FileDescriptor() {
          close(FD);
        }
      };
      static FileDescriptor nullDev;
      return nullDev.FD;
    }
#endif

    // Checking whether the pointer points to a valid memory location
    bool isAddressValid(const void *P) {
      if (!P || P == (void *) -1)
        return false;

#ifdef LLVM_ON_WIN32
      MEMORY_BASIC_INFORMATION MBI;
      if (!VirtualQuery(P, &MBI, sizeof(MBI)))
        return false;
      if (MBI.State != MEM_COMMIT)
        return false;
      return true;
#else
      // Look-up the address in the cache.
      Cache& currentCache = getCache();
      if (currentCache.contains(P))
        return true;
      // There is a POSIX way of finding whether an address
      // can be accessed for reading.
      if (write(getNullDevFileDescriptor(), P, 1/*byte*/) != 1) {
        assert(errno == EFAULT && "unexpected write error at address");
        return false;
      }
      currentCache.push(P);
      return true;
#endif
    }
  }
}
<|endoftext|>


<commit_before>#include "Text.h"

namespace hm
{
	Text::Text()
	{
        text = "Hume Library";
        setPosition(0, 0);
	}

	Text::Text(std::string text, Font& font)
	{
		this->text = text;
        sdltext = NULL;
        setText(text, font);
        setPosition(0, 0);
	}

    Text::~Text()
    {
        if(sdltext != NULL)
        {
            SDL_FreeSurface(sdltext);
            sdltext = NULL;
        }
    }

	SDL_Surface* Text::getSurface()
    {
		return sdltext;
	}

	void Text::setText(std::string text, Font& font)
	{
		this->text = text;

		// Check for font.
		if(font.getFont() == NULL)
		{
			std::cout << "Can't set text. Font is NULL." << std::endl;
			return;
        }

		RenderMode rm = font.getRenderMode();
        if(rm == SOLID)
            sdltext = TTF_RenderText_Solid(font.getFont(), text.c_str(), font.getColor());
        if(rm == SHADED)
            sdltext = TTF_RenderText_Shaded(font.getFont(), text.c_str(), font.getColor(), font.getbColor());
        if(rm == BLENDED)
			sdltext = TTF_RenderText_Blended(font.getFont(), text.c_str(), font.getColor());
        optimize();

		return;
	}

	std::string Text::getText()
	{
		return text;
    }

    void Text::setPosition(int x, int y)
    {
        position.x = x;
        position.y = y;
        return;
    }

	SDL_Rect* Text::getPosition()
    {
		return &position;
	}

    void Text::optimize()
    {
        SDL_Surface* unoptimizedText = sdltext;
        sdltext = SDL_DisplayFormat(unoptimizedText);
        SDL_FreeSurface(unoptimizedText);

        return;
    }
}
<commit_msg>Modified Text class default constructor.<commit_after>#include "Text.h"

namespace hm
{
	Text::Text()
	{
        text = "Hume Library";
        sdltext = NULL;
        setPosition(0, 0);
	}

	Text::Text(std::string text, Font& font)
	{
		this->text = text;
        sdltext = NULL;
        setText(text, font);
        setPosition(0, 0);
	}

    Text::~Text()
    {
        if(sdltext != NULL)
        {
            SDL_FreeSurface(sdltext);
            sdltext = NULL;
        }
    }

	SDL_Surface* Text::getSurface()
    {
		return sdltext;
	}

	void Text::setText(std::string text, Font& font)
	{
		this->text = text;

		// Check for font.
		if(font.getFont() == NULL)
		{
			std::cout << "Can't set text. Font is NULL." << std::endl;
			return;
        }

		RenderMode rm = font.getRenderMode();
        if(rm == SOLID)
            sdltext = TTF_RenderText_Solid(font.getFont(), text.c_str(), font.getColor());
        if(rm == SHADED)
            sdltext = TTF_RenderText_Shaded(font.getFont(), text.c_str(), font.getColor(), font.getbColor());
        if(rm == BLENDED)
			sdltext = TTF_RenderText_Blended(font.getFont(), text.c_str(), font.getColor());
        optimize();

		return;
	}

	std::string Text::getText()
	{
		return text;
    }

    void Text::setPosition(int x, int y)
    {
        position.x = x;
        position.y = y;
        return;
    }

	SDL_Rect* Text::getPosition()
    {
		return &position;
	}

    void Text::optimize()
    {
        SDL_Surface* unoptimizedText = sdltext;
        sdltext = SDL_DisplayFormat(unoptimizedText);
        SDL_FreeSurface(unoptimizedText);

        return;
    }
}
<|endoftext|>


<commit_before>// ---------------------------------------------------------------------
// $Id: tria.cc 32807 2014-04-22 15:01:57Z heister $
//
// Copyright (C) 2015, 2016 by the deal.II authors
//
// This file is part of the deal.II library.
//
// The deal.II library is free software; you can use it, 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 2.1 of the License, or (at your option) any later version.
// The full text of the license can be found in the file LICENSE at
// the top level of the deal.II distribution.
//
// ---------------------------------------------------------------------

#include <deal.II/base/utilities.h>
#include <deal.II/base/mpi.h>
#include <deal.II/grid/tria.h>
#include <deal.II/grid/tria_accessor.h>
#include <deal.II/grid/tria_iterator.h>
#include <deal.II/grid/grid_tools.h>
#include <deal.II/grid/filtered_iterator.h>
#include <deal.II/distributed/shared_tria.h>
#include <deal.II/distributed/tria.h>

DEAL_II_NAMESPACE_OPEN

#ifdef DEAL_II_WITH_MPI
namespace parallel
{
  namespace shared
  {

    template <int dim, int spacedim>
    Triangulation<dim,spacedim>::Triangulation (MPI_Comm mpi_communicator,
                                                const typename dealii::Triangulation<dim,spacedim>::MeshSmoothing smooth_grid,
                                                const bool allow_artificial_cells):
      dealii::parallel::Triangulation<dim,spacedim>(mpi_communicator,smooth_grid,false),
      allow_artificial_cells(allow_artificial_cells)
    {
    }

    template <int dim, int spacedim>
    void Triangulation<dim,spacedim>::partition()
    {
      dealii::GridTools::partition_triangulation (this->n_subdomains, *this);

      true_subdomain_ids_of_cells.resize(this->n_active_cells());

      // loop over all cells and mark artificial:
      typename parallel::shared::Triangulation<dim,spacedim>::active_cell_iterator
      cell = this->begin_active(),
      endc = this->end();

      if (allow_artificial_cells)
        {
          // get halo layer of (ghost) cells
          // parallel::shared::Triangulation<dim>::
          std_cxx11::function<bool (const typename parallel::shared::Triangulation<dim,spacedim>::active_cell_iterator &)> predicate
            = IteratorFilters::SubdomainEqualTo(this->my_subdomain);

          const std::vector<typename parallel::shared::Triangulation<dim,spacedim>::active_cell_iterator>
          active_halo_layer_vector = GridTools::compute_active_cell_halo_layer (*this, predicate);
          std::set<typename parallel::shared::Triangulation<dim,spacedim>::active_cell_iterator>
          active_halo_layer(active_halo_layer_vector.begin(), active_halo_layer_vector.end());

          for (unsigned int index=0; cell != endc; cell++, index++)
            {
              // store original/true subdomain ids:
              true_subdomain_ids_of_cells[index] = cell->subdomain_id();

              if (cell->is_locally_owned() == false &&
                  active_halo_layer.find(cell) == active_halo_layer.end())
                cell->set_subdomain_id(numbers::artificial_subdomain_id);
            }
        }
      else
        {
          // just store true subdomain ids
          for (unsigned int index=0; cell != endc; cell++, index++)
            true_subdomain_ids_of_cells[index] = cell->subdomain_id();

        }
    }

    template <int dim, int spacedim>
    bool
    Triangulation<dim,spacedim>::with_artificial_cells() const
    {
      return allow_artificial_cells;
    }

    template <int dim, int spacedim>
    const std::vector<types::subdomain_id> &
    Triangulation<dim,spacedim>::get_true_subdomain_ids_of_cells() const
    {
      return true_subdomain_ids_of_cells;
    }

    template <int dim, int spacedim>
    Triangulation<dim,spacedim>::~Triangulation ()
    {

    }

    template <int dim, int spacedim>
    void
    Triangulation<dim,spacedim>::execute_coarsening_and_refinement ()
    {
      dealii::Triangulation<dim,spacedim>::execute_coarsening_and_refinement ();
      partition();
      this->update_number_cache ();
    }

    template <int dim, int spacedim>
    void
    Triangulation<dim,spacedim>::create_triangulation (const std::vector< Point< spacedim > > &vertices,
                                                       const std::vector< CellData< dim > > &cells,
                                                       const SubCellData &subcelldata)
    {
      try
        {
          dealii::Triangulation<dim,spacedim>::
          create_triangulation (vertices, cells, subcelldata);
        }
      catch (const typename dealii::Triangulation<dim,spacedim>::DistortedCellList &)
        {
          // the underlying triangulation should not be checking for distorted
          // cells
          AssertThrow (false, ExcInternalError());
        }
      partition();
      this->update_number_cache ();
    }

    template <int dim, int spacedim>
    void
    Triangulation<dim, spacedim>::
    copy_triangulation (const dealii::Triangulation<dim, spacedim> &other_tria)
    {
      Assert ((dynamic_cast<const dealii::parallel::distributed::Triangulation<dim,spacedim> *>(&other_tria) == NULL),
              ExcMessage("Cannot use this function on parallel::distributed::Triangulation."));

      dealii::parallel::Triangulation<dim,spacedim>::copy_triangulation (other_tria);
      partition();
      this->update_number_cache ();
    }

  }
}

#else

namespace parallel
{
  namespace shared
  {
    template <int dim, int spacedim>
    Triangulation<dim,spacedim>::Triangulation ()
      :
      dealii::parallel::Triangulation<dim,spacedim>(MPI_COMM_SELF)
    {
      Assert (false, ExcNotImplemented());
    }

    template <int dim, int spacedim>
    bool
    Triangulation<dim,spacedim>::with_artificial_cells() const
    {
      Assert (false, ExcNotImplemented());
      return true;
    }

    template <int dim, int spacedim>
    const std::vector<unsigned int> &
    Triangulation<dim,spacedim>::get_true_subdomain_ids_of_cells() const
    {
      Assert (false, ExcNotImplemented());
      return true_subdomain_ids_of_cells;
    }

  }
}

#endif

/*-------------- Explicit Instantiations -------------------------------*/
#include "shared_tria.inst"

DEAL_II_NAMESPACE_CLOSE
<commit_msg>Just minor style updates.<commit_after>// ---------------------------------------------------------------------
// $Id: tria.cc 32807 2014-04-22 15:01:57Z heister $
//
// Copyright (C) 2015, 2016 by the deal.II authors
//
// This file is part of the deal.II library.
//
// The deal.II library is free software; you can use it, 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 2.1 of the License, or (at your option) any later version.
// The full text of the license can be found in the file LICENSE at
// the top level of the deal.II distribution.
//
// ---------------------------------------------------------------------

#include <deal.II/base/utilities.h>
#include <deal.II/base/mpi.h>
#include <deal.II/grid/tria.h>
#include <deal.II/grid/tria_accessor.h>
#include <deal.II/grid/tria_iterator.h>
#include <deal.II/grid/grid_tools.h>
#include <deal.II/grid/filtered_iterator.h>
#include <deal.II/distributed/shared_tria.h>
#include <deal.II/distributed/tria.h>

DEAL_II_NAMESPACE_OPEN

#ifdef DEAL_II_WITH_MPI
namespace parallel
{
  namespace shared
  {

    template <int dim, int spacedim>
    Triangulation<dim,spacedim>::Triangulation (MPI_Comm mpi_communicator,
                                                const typename dealii::Triangulation<dim,spacedim>::MeshSmoothing smooth_grid,
                                                const bool allow_artificial_cells):
      dealii::parallel::Triangulation<dim,spacedim>(mpi_communicator,smooth_grid,false),
      allow_artificial_cells(allow_artificial_cells)
    {}

    template <int dim, int spacedim>
    void Triangulation<dim,spacedim>::partition()
    {
      dealii::GridTools::partition_triangulation (this->n_subdomains, *this);

      true_subdomain_ids_of_cells.resize(this->n_active_cells());

      // loop over all cells and mark artificial:
      typename parallel::shared::Triangulation<dim,spacedim>::active_cell_iterator
      cell = this->begin_active(),
      endc = this->end();

      if (allow_artificial_cells)
        {
          // get halo layer of (ghost) cells
          // parallel::shared::Triangulation<dim>::
          std_cxx11::function<bool (const typename parallel::shared::Triangulation<dim,spacedim>::active_cell_iterator &)> predicate
            = IteratorFilters::SubdomainEqualTo(this->my_subdomain);

          const std::vector<typename parallel::shared::Triangulation<dim,spacedim>::active_cell_iterator>
          active_halo_layer_vector = GridTools::compute_active_cell_halo_layer (*this, predicate);
          std::set<typename parallel::shared::Triangulation<dim,spacedim>::active_cell_iterator>
          active_halo_layer(active_halo_layer_vector.begin(), active_halo_layer_vector.end());

          for (unsigned int index=0; cell != endc; cell++, index++)
            {
              // store original/true subdomain ids:
              true_subdomain_ids_of_cells[index] = cell->subdomain_id();

              if (cell->is_locally_owned() == false &&
                  active_halo_layer.find(cell) == active_halo_layer.end())
                cell->set_subdomain_id(numbers::artificial_subdomain_id);
            }
        }
      else
        {
          // just store true subdomain ids
          for (unsigned int index=0; cell != endc; cell++, index++)
            true_subdomain_ids_of_cells[index] = cell->subdomain_id();

        }
    }

    template <int dim, int spacedim>
    bool
    Triangulation<dim,spacedim>::with_artificial_cells() const
    {
      return allow_artificial_cells;
    }

    template <int dim, int spacedim>
    const std::vector<types::subdomain_id> &
    Triangulation<dim,spacedim>::get_true_subdomain_ids_of_cells() const
    {
      return true_subdomain_ids_of_cells;
    }

    template <int dim, int spacedim>
    Triangulation<dim,spacedim>::~Triangulation ()
    {}

    template <int dim, int spacedim>
    void
    Triangulation<dim,spacedim>::execute_coarsening_and_refinement ()
    {
      dealii::Triangulation<dim,spacedim>::execute_coarsening_and_refinement ();
      partition();
      this->update_number_cache ();
    }

    template <int dim, int spacedim>
    void
    Triangulation<dim,spacedim>::create_triangulation (const std::vector< Point< spacedim > > &vertices,
                                                       const std::vector< CellData< dim > > &cells,
                                                       const SubCellData &subcelldata)
    {
      try
        {
          dealii::Triangulation<dim,spacedim>::
          create_triangulation (vertices, cells, subcelldata);
        }
      catch (const typename dealii::Triangulation<dim,spacedim>::DistortedCellList &)
        {
          // the underlying triangulation should not be checking for distorted
          // cells
          AssertThrow (false, ExcInternalError());
        }
      partition();
      this->update_number_cache ();
    }

    template <int dim, int spacedim>
    void
    Triangulation<dim, spacedim>::
    copy_triangulation (const dealii::Triangulation<dim, spacedim> &other_tria)
    {
      Assert ((dynamic_cast<const dealii::parallel::distributed::Triangulation<dim,spacedim> *>(&other_tria) == NULL),
              ExcMessage("Cannot use this function on parallel::distributed::Triangulation."));

      dealii::parallel::Triangulation<dim,spacedim>::copy_triangulation (other_tria);
      partition();
      this->update_number_cache ();
    }

  }
}

#else

namespace parallel
{
  namespace shared
  {
    template <int dim, int spacedim>
    Triangulation<dim,spacedim>::Triangulation ()
      :
      dealii::parallel::Triangulation<dim,spacedim>(MPI_COMM_SELF)
    {
      Assert (false, ExcNotImplemented());
    }

    template <int dim, int spacedim>
    bool
    Triangulation<dim,spacedim>::with_artificial_cells() const
    {
      Assert (false, ExcNotImplemented());
      return true;
    }

    template <int dim, int spacedim>
    const std::vector<unsigned int> &
    Triangulation<dim,spacedim>::get_true_subdomain_ids_of_cells() const
    {
      Assert (false, ExcNotImplemented());
      return true_subdomain_ids_of_cells;
    }

  }
}

#endif

/*-------------- Explicit Instantiations -------------------------------*/
#include "shared_tria.inst"

DEAL_II_NAMESPACE_CLOSE
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
 * This file is part of the libetonyek project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include "IWORKPElement.h"

#include "IWORKBrContext.h"
#include "IWORKDictionary.h"
#include "IWORKLinkElement.h"
#include "IWORKSpanElement.h"
#include "IWORKStyle.h"
#include "IWORKTabElement.h"
#include "IWORKText.h"
#include "IWORKToken.h"
#include "IWORKXMLParserState.h"
#include "libetonyek_xml.h"

namespace libetonyek
{

IWORKPElement::IWORKPElement(IWORKXMLParserState &state)
  : IWORKXMLMixedContextBase(state)
  , m_style()
  , m_opened(false)
{
}

void IWORKPElement::attribute(const int name, const char *const value)
{
  switch (name)
  {
  case IWORKToken::NS_URI_SF | IWORKToken::list_level :
    m_listLevel = try_int_cast(value);
    break;
  case IWORKToken::NS_URI_SF | IWORKToken::style :
  {
    const IWORKStyleMap_t::const_iterator it = getState().getDictionary().m_paragraphStyles.find(value);
    if (getState().getDictionary().m_paragraphStyles.end() != it)
      m_style = it->second;
    break;
  }
  }
}

IWORKXMLContextPtr_t IWORKPElement::element(const int name)
{
  ensureOpened();

  switch (name)
  {
  case IWORKToken::NS_URI_SF | IWORKToken::crbr :
  case IWORKToken::NS_URI_SF | IWORKToken::intratopicbr :
  case IWORKToken::NS_URI_SF | IWORKToken::lnbr :
    return makeContext<IWORKBrContext>(getState());
  case IWORKToken::NS_URI_SF | IWORKToken::span :
    return makeContext<IWORKSpanElement>(getState());
  case IWORKToken::NS_URI_SF | IWORKToken::tab :
    return makeContext<IWORKTabElement>(getState());
  case IWORKToken::NS_URI_SF | IWORKToken::link :
    return makeContext<IWORKLinkElement>(getState());
  }

  return IWORKXMLContextPtr_t();
}

void IWORKPElement::text(const char *const value)
{
  ensureOpened();
  if (bool(getState().m_currentText))
    getState().m_currentText->insertText(value);
}

void IWORKPElement::endOfElement()
{
  ensureOpened();
  if (bool(getState().m_currentText))
  {
    getState().m_currentText->flushParagraph();
    getState().m_currentText->setListLevel(0);
  }
}

void IWORKPElement::ensureOpened()
{
  if (!m_opened)
  {
    if (bool(getState().m_currentText))
    {
      getState().m_currentText->setParagraphStyle(m_style);
      if (m_listLevel)
        getState().m_currentText->setListLevel(get(m_listLevel));
      getState().m_currentText->setListStyle(m_style);
    }
    m_opened = true;
  }
}

}

/* vim:set shiftwidth=2 softtabstop=2 expandtab: */
<commit_msg>disable handling of lists in Keynote 5 for now<commit_after>/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
 * This file is part of the libetonyek project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include "IWORKPElement.h"

#include "IWORKBrContext.h"
#include "IWORKDictionary.h"
#include "IWORKLinkElement.h"
#include "IWORKSpanElement.h"
#include "IWORKStyle.h"
#include "IWORKTabElement.h"
#include "IWORKText.h"
#include "IWORKToken.h"
#include "IWORKXMLParserState.h"
#include "libetonyek_xml.h"

namespace libetonyek
{

IWORKPElement::IWORKPElement(IWORKXMLParserState &state)
  : IWORKXMLMixedContextBase(state)
  , m_style()
  , m_opened(false)
{
}

void IWORKPElement::attribute(const int name, const char *const value)
{
  switch (name)
  {
  case IWORKToken::NS_URI_SF | IWORKToken::list_level :
    m_listLevel = try_int_cast(value);
    break;
  case IWORKToken::NS_URI_SF | IWORKToken::style :
  {
    const IWORKStyleMap_t::const_iterator it = getState().getDictionary().m_paragraphStyles.find(value);
    if (getState().getDictionary().m_paragraphStyles.end() != it)
      m_style = it->second;
    break;
  }
  }
}

IWORKXMLContextPtr_t IWORKPElement::element(const int name)
{
  ensureOpened();

  switch (name)
  {
  case IWORKToken::NS_URI_SF | IWORKToken::crbr :
  case IWORKToken::NS_URI_SF | IWORKToken::intratopicbr :
  case IWORKToken::NS_URI_SF | IWORKToken::lnbr :
    return makeContext<IWORKBrContext>(getState());
  case IWORKToken::NS_URI_SF | IWORKToken::span :
    return makeContext<IWORKSpanElement>(getState());
  case IWORKToken::NS_URI_SF | IWORKToken::tab :
    return makeContext<IWORKTabElement>(getState());
  case IWORKToken::NS_URI_SF | IWORKToken::link :
    return makeContext<IWORKLinkElement>(getState());
  }

  return IWORKXMLContextPtr_t();
}

void IWORKPElement::text(const char *const value)
{
  ensureOpened();
  if (bool(getState().m_currentText))
    getState().m_currentText->insertText(value);
}

void IWORKPElement::endOfElement()
{
  ensureOpened();
  if (bool(getState().m_currentText))
  {
    getState().m_currentText->flushParagraph();
    // getState().m_currentText->setListLevel(0);
  }
}

void IWORKPElement::ensureOpened()
{
  if (!m_opened)
  {
    if (bool(getState().m_currentText))
    {
      getState().m_currentText->setParagraphStyle(m_style);
      // if (m_listLevel)
      // getState().m_currentText->setListLevel(get(m_listLevel));
      getState().m_currentText->setListStyle(m_style);
    }
    m_opened = true;
  }
}

}

/* vim:set shiftwidth=2 softtabstop=2 expandtab: */
<|endoftext|>


<commit_before>// -*- Mode:C++ -*-

/**************************************************************************************************/
/*                                                                                */
/* Copyright (C) 2014 University of Hull                                                          */
/*                                                                                */
/**************************************************************************************************/
/*                                                                                */
/*  module     :  field/test/value_multi.cpp                                                      */
/*  project    :                                                                                */
/*  description:                                                                                */
/*                                                                                */
/**************************************************************************************************/

// includes, system

//#include <>

// includes, project

#include <field/value_multi.hpp>
#include <shared.hpp>

// internal unnamed namespace

namespace {

  // types, internal (class, enum, struct, union, typedef)

  // variables, internal

  // functions, internal

} // namespace {

#define BOOST_TEST_MAIN
#include <boost/test/unit_test.hpp>
#include <boost/test/test_case_template.hpp>

BOOST_AUTO_TEST_CASE_TEMPLATE(value_multi_get, T, field::test::multi_types)
{
  using namespace field;

  test::container_multi<T>                   c;
  value::multi<typename T::value_type> const f(c, "f");

  BOOST_CHECK(T() == f.get());
}

BOOST_AUTO_TEST_CASE_TEMPLATE(value_multi_set, T, field::test::multi_types)
{
  using namespace field;

  test::container_multi<T>             c;
  value::multi<typename T::value_type> f(c, "f");

  BOOST_CHECK(T() == f.set(T()));
}

BOOST_AUTO_TEST_CASE_TEMPLATE(value_multi_add, T, field::test::multi_types)
{
  using namespace field;

  test::container_multi<T>             c;
  value::multi<typename T::value_type> f(c, "f");

  f.add(typename T::value_type());

  BOOST_CHECK(1 == f.get().size());
}

BOOST_AUTO_TEST_CASE_TEMPLATE(value_multi_sub, T, field::test::multi_types)
{
  using namespace field;

  test::container_multi<T>             c;
  value::multi<typename T::value_type> f(c, "f", T(2));

  f.sub(typename T::value_type());

  BOOST_CHECK(1 == f.get().size());
}

BOOST_AUTO_TEST_CASE_TEMPLATE(value_multi_set_initlist, T, field::test::multi_types)
{
  using namespace field;

  test::container_multi<T>             c;
  value::multi<typename T::value_type> f(c, "f");

  BOOST_CHECK(T() == f.set({ }));
}

BOOST_AUTO_TEST_CASE_TEMPLATE(value_multi_op_convert, T, field::test::multi_types)
{
  using namespace field;

  test::container_multi<T>                   c;
  value::multi<typename T::value_type> const f(c, "f");

  BOOST_CHECK(T() == static_cast<T>(f));
}

BOOST_AUTO_TEST_CASE_TEMPLATE(value_multi_op_assign, T, field::test::multi_types)
{
  using namespace field;

  test::container_multi<T>             c;
  value::multi<typename T::value_type> f(c, "f");

  BOOST_CHECK(T() == static_cast<T>(f = T()));
}

BOOST_AUTO_TEST_CASE_TEMPLATE(value_multi_op_assign_initlist, T, field::test::multi_types)
{
  using namespace field;

  test::container_multi<T>             c;
  value::multi<typename T::value_type> f(c, "f");

  BOOST_CHECK(T() == static_cast<T>(f = { }));
}

BOOST_AUTO_TEST_CASE_TEMPLATE(value_multi_op_add, T, field::test::multi_types)
{
  using namespace field;

  test::container_multi<T>             c;
  value::multi<typename T::value_type> f(c, "f");

  f += typename T::value_type();

  BOOST_CHECK(1 == f.get().size());
}

BOOST_AUTO_TEST_CASE_TEMPLATE(value_multi_op_sub, T, field::test::multi_types)
{
  using namespace field;

  test::container_multi<T>             c;
  value::multi<typename T::value_type> f(c, "f", T(2));

  f -= typename T::value_type();

  BOOST_CHECK(1 == f.get().size());
}
<commit_msg>add'l checks<commit_after>// -*- Mode:C++ -*-

/**************************************************************************************************/
/*                                                                                */
/* Copyright (C) 2014 University of Hull                                                          */
/*                                                                                */
/**************************************************************************************************/
/*                                                                                */
/*  module     :  field/test/value_multi.cpp                                                      */
/*  project    :                                                                                */
/*  description:                                                                                */
/*                                                                                */
/**************************************************************************************************/

// includes, system

//#include <>

// includes, project

#include <field/value_multi.hpp>
#include <shared.hpp>

// internal unnamed namespace

namespace {

  // types, internal (class, enum, struct, union, typedef)

  // variables, internal

  // functions, internal

} // namespace {

#define BOOST_TEST_MAIN
#include <boost/test/unit_test.hpp>
#include <boost/test/test_case_template.hpp>

BOOST_AUTO_TEST_CASE_TEMPLATE(value_multi_get, T, field::test::multi_types)
{
  using namespace field;

  test::container_multi<T>                   c;
  value::multi<typename T::value_type> const f(c, "f");

  BOOST_CHECK(T() == f.get());
}

BOOST_AUTO_TEST_CASE_TEMPLATE(value_multi_set, T, field::test::multi_types)
{
  using namespace field;

  test::container_multi<T>             c;
  value::multi<typename T::value_type> f(c, "f");

  BOOST_CHECK(T() == f.set(T()));
}

BOOST_AUTO_TEST_CASE_TEMPLATE(value_multi_add, T, field::test::multi_types)
{
  using namespace field;

  test::container_multi<T>             c;
  value::multi<typename T::value_type> f(c, "f");

  BOOST_CHECK(f.add(typename T::value_type()));
  BOOST_CHECK(1 == f.get().size());
}

BOOST_AUTO_TEST_CASE_TEMPLATE(value_multi_sub, T, field::test::multi_types)
{
  using namespace field;

  test::container_multi<T>             c;
  value::multi<typename T::value_type> f(c, "f", T(2));

  BOOST_CHECK(f.sub(typename T::value_type()));
  BOOST_CHECK(1 == f.get().size());
}

BOOST_AUTO_TEST_CASE_TEMPLATE(value_multi_set_initlist, T, field::test::multi_types)
{
  using namespace field;

  test::container_multi<T>             c;
  value::multi<typename T::value_type> f(c, "f");

  BOOST_CHECK(T() == f.set({ }));
}

BOOST_AUTO_TEST_CASE_TEMPLATE(value_multi_op_convert, T, field::test::multi_types)
{
  using namespace field;

  test::container_multi<T>                   c;
  value::multi<typename T::value_type> const f(c, "f");

  BOOST_CHECK(T() == static_cast<T>(f));
}

BOOST_AUTO_TEST_CASE_TEMPLATE(value_multi_op_assign, T, field::test::multi_types)
{
  using namespace field;

  test::container_multi<T>             c;
  value::multi<typename T::value_type> f(c, "f");

  BOOST_CHECK(T() == static_cast<T>(f = T()));
}

BOOST_AUTO_TEST_CASE_TEMPLATE(value_multi_op_assign_initlist, T, field::test::multi_types)
{
  using namespace field;

  test::container_multi<T>             c;
  value::multi<typename T::value_type> f(c, "f");

  BOOST_CHECK(T() == static_cast<T>(f = { }));
}

BOOST_AUTO_TEST_CASE_TEMPLATE(value_multi_op_add, T, field::test::multi_types)
{
  using namespace field;

  test::container_multi<T>             c;
  value::multi<typename T::value_type> f(c, "f");

  f += typename T::value_type();

  BOOST_CHECK(1 == f.get().size());
}

BOOST_AUTO_TEST_CASE_TEMPLATE(value_multi_op_sub, T, field::test::multi_types)
{
  using namespace field;

  test::container_multi<T>             c;
  value::multi<typename T::value_type> f(c, "f", T(2));

  f -= typename T::value_type();

  BOOST_CHECK(1 == f.get().size());
}
<|endoftext|>


<commit_before>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/

#include "CppDocument.h"
#include "CppBindings.h"
#include "FastPreprocessor.h"

#include <Control.h>
#include <TranslationUnit.h>
#include <DiagnosticClient.h>
#include <Semantic.h>
#include <Literals.h>
#include <Symbols.h>
#include <AST.h>
#include <Scope.h>

#include <QtCore/QByteArray>
#include <QtCore/QBitArray>
#include <QtCore/QDir>
#include <QtCore/QtDebug>

/*!
    \namespace CPlusPlus
    The namespace for C++ related tools.
*/

using namespace CPlusPlus;

namespace {

class DocumentDiagnosticClient : public DiagnosticClient
{
    enum { MAX_MESSAGE_COUNT = 10 };

public:
    DocumentDiagnosticClient(Document *doc, QList<Document::DiagnosticMessage> *messages)
        : doc(doc),
          messages(messages),
          errorCount(0)
    { }

    virtual void report(int level,
                        const StringLiteral *fileId,
                        unsigned line, unsigned column,
                        const char *format, va_list ap)
    {
        if (level == Error) {
            ++errorCount;

            if (errorCount >= MAX_MESSAGE_COUNT)
                return; // ignore the error
        }

        const QString fileName = QString::fromUtf8(fileId->chars(), fileId->size());

        if (fileName != doc->fileName())
            return;

        QString message;
        message.vsprintf(format, ap);

        Document::DiagnosticMessage m(convertLevel(level), doc->fileName(),
                                      line, column, message);
        messages->append(m);
    }

    static int convertLevel(int level) {
        switch (level) {
            case Warning: return Document::DiagnosticMessage::Warning;
            case Error:   return Document::DiagnosticMessage::Error;
            case Fatal:   return Document::DiagnosticMessage::Fatal;
            default:      return Document::DiagnosticMessage::Error;
        }
    }

private:
    Document *doc;
    QList<Document::DiagnosticMessage> *messages;
    int errorCount;
};

} // anonymous namespace

Document::Document(const QString &fileName)
    : _fileName(QDir::cleanPath(fileName)),
      _globalNamespace(0),
      _revision(0),
      _editorRevision(0)
{
    _control = new Control();

    _control->setDiagnosticClient(new DocumentDiagnosticClient(this, &_diagnosticMessages));

    const QByteArray localFileName = fileName.toUtf8();
    const StringLiteral *fileId = _control->findOrInsertStringLiteral(localFileName.constData(),
                                                                      localFileName.size());
    _translationUnit = new TranslationUnit(_control, fileId);
    _translationUnit->setQtMocRunEnabled(true);
    _translationUnit->setCxxOxEnabled(true);
    _translationUnit->setObjCEnabled(true);
    (void) _control->switchTranslationUnit(_translationUnit);
}

Document::~Document()
{
    delete _translationUnit;
    delete _control->diagnosticClient();
    delete _control;
}

Control *Document::control() const
{
    return _control;
}

unsigned Document::revision() const
{
    return _revision;
}

void Document::setRevision(unsigned revision)
{
    _revision = revision;
}

unsigned Document::editorRevision() const
{
    return _editorRevision;
}

void Document::setEditorRevision(unsigned editorRevision)
{
    _editorRevision = editorRevision;
}

QDateTime Document::lastModified() const
{
    return _lastModified;
}

void Document::setLastModified(const QDateTime &lastModified)
{
    _lastModified = lastModified;
}

QString Document::fileName() const
{
    return _fileName;
}

QStringList Document::includedFiles() const
{
    QStringList files;
    foreach (const Include &i, _includes)
        files.append(i.fileName());
    files.removeDuplicates();
    return files;
}

void Document::addIncludeFile(const QString &fileName, unsigned line)
{
    _includes.append(Include(QDir::cleanPath(fileName), line));
}

void Document::appendMacro(const Macro &macro)
{
    _definedMacros.append(macro);
}

void Document::addMacroUse(const Macro &macro, unsigned offset, unsigned length,
                           unsigned beginLine,
                           const QVector<MacroArgumentReference> &actuals, bool inCondition)
{
    MacroUse use(macro, offset, offset + length, beginLine);
    use.setInCondition(inCondition);

    foreach (const MacroArgumentReference &actual, actuals) {
        const Block arg(actual.position(), actual.position() + actual.length());

        use.addArgument(arg);
    }

    _macroUses.append(use);
}

void Document::addUndefinedMacroUse(const QByteArray &name, unsigned offset)
{
    QByteArray copy(name.data(), name.size());
    UndefinedMacroUse use(copy, offset);
    _undefinedMacroUses.append(use);
}

/*!
    \class Document::MacroUse
    \brief Represents the usage of a macro in a \l {Document}.
    \sa Document::UndefinedMacroUse
*/

/*!
    \class Document::UndefinedMacroUse
    \brief Represents a macro that was looked up, but not found.

    Holds data about the reference to a macro in an \tt{#ifdef} or \tt{#ifndef}
    or argument to the \tt{defined} operator inside an \tt{#if} or \tt{#elif} that does
    not exist.

    \sa Document::undefinedMacroUses(), Document::MacroUse, Macro
*/

/*!
    \fn QByteArray Document::UndefinedMacroUse::name() const

    Returns the name of the macro that was not found.
*/

/*!
    \fn QList<UndefinedMacroUse> Document::undefinedMacroUses() const

    Returns a list of referenced but undefined macros.

    \sa Document::macroUses(), Document::definedMacros(), Macro
*/

/*!
    \fn QList<MacroUse> Document::macroUses() const

    Returns a list of macros used.

    \sa Document::undefinedMacroUses(), Document::definedMacros(), Macro
*/

/*!
    \fn QList<Macro> Document::definedMacros() const

    Returns the list of macros defined.

    \sa Document::macroUses(), Document::undefinedMacroUses()
*/

TranslationUnit *Document::translationUnit() const
{
    return _translationUnit;
}

bool Document::skipFunctionBody() const
{
    return _translationUnit->skipFunctionBody();
}

void Document::setSkipFunctionBody(bool skipFunctionBody)
{
    _translationUnit->setSkipFunctionBody(skipFunctionBody);
}

unsigned Document::globalSymbolCount() const
{
    if (! _globalNamespace)
        return 0;

    return _globalNamespace->memberCount();
}

Symbol *Document::globalSymbolAt(unsigned index) const
{
    return _globalNamespace->memberAt(index);
}

Scope *Document::globalSymbols() const
{
    if (! _globalNamespace)
        return 0;

    return _globalNamespace->members();
}

Namespace *Document::globalNamespace() const
{
    return _globalNamespace;
}

void Document::setGlobalNamespace(Namespace *globalNamespace)
{
    _globalNamespace = globalNamespace;
}

Symbol *Document::findSymbolAt(unsigned line, unsigned column) const
{
    return findSymbolAt(line, column, globalSymbols());
}

Symbol *Document::findSymbolAt(unsigned line, unsigned column, Scope *scope) const
{
    Symbol *previousSymbol = 0;

    for (unsigned i = 0; i < scope->symbolCount(); ++i) {
        Symbol *symbol = scope->symbolAt(i);
        if (symbol->line() > line)
            break;

        previousSymbol = symbol;
    }

    if (previousSymbol) {
        if (ScopedSymbol *scoped = previousSymbol->asScopedSymbol()) {
            if (Symbol *member = findSymbolAt(line, column, scoped->members()))
                return member;
        }
    }

    return previousSymbol;
}

const Macro *Document::findMacroDefinitionAt(unsigned line) const
{
    foreach (const Macro &macro, _definedMacros) {
        if (macro.line() == line)
            return &macro;
    }
    return 0;
}

const Document::MacroUse *Document::findMacroUseAt(unsigned offset) const
{
    foreach (const Document::MacroUse &use, _macroUses) {
        if (use.contains(offset))
            return &use;
    }
    return 0;
}

const Document::UndefinedMacroUse *Document::findUndefinedMacroUseAt(unsigned offset) const
{
    foreach (const Document::UndefinedMacroUse &use, _undefinedMacroUses) {
        if (use.contains(offset))
            return &use;
    }
    return 0;
}

Document::Ptr Document::create(const QString &fileName)
{
    Document::Ptr doc(new Document(fileName));
    return doc;
}

QByteArray Document::source() const
{ return _source; }

void Document::setSource(const QByteArray &source)
{
    _source = source;
    _translationUnit->setSource(_source.constBegin(), _source.size());
}

void Document::startSkippingBlocks(unsigned start)
{
    _skippedBlocks.append(Block(start, 0));
}

void Document::stopSkippingBlocks(unsigned stop)
{
    if (_skippedBlocks.isEmpty())
        return;

    unsigned start = _skippedBlocks.back().begin();
    if (start > stop)
        _skippedBlocks.removeLast(); // Ignore this block, it's invalid.
    else
        _skippedBlocks.back() = Block(start, stop);
}

bool Document::isTokenized() const
{
    return _translationUnit->isTokenized();
}

void Document::tokenize()
{
    _translationUnit->tokenize();
}

bool Document::isParsed() const
{
    return _translationUnit->isParsed();
}

bool Document::parse(ParseMode mode)
{
    TranslationUnit::ParseMode m = TranslationUnit::ParseTranlationUnit;
    switch (mode) {
    case ParseTranlationUnit:
        m = TranslationUnit::ParseTranlationUnit;
        break;

    case ParseDeclaration:
        m = TranslationUnit::ParseDeclaration;
        break;

    case ParseExpression:
        m = TranslationUnit::ParseExpression;
        break;

    case ParseDeclarator:
        m = TranslationUnit::ParseDeclarator;
        break;

    case ParseStatement:
        m = TranslationUnit::ParseStatement;
        break;

    default:
        break;
    }

    return _translationUnit->parse(m);
}

void Document::check(CheckMode mode)
{
    Q_ASSERT(!_globalNamespace);

    if (! isParsed())
        parse();

    Semantic semantic(_translationUnit);
    if (mode == FastCheck)
        semantic.setSkipFunctionBodies(true);

    _globalNamespace = _control->newNamespace(0);
    Scope *globals = _globalNamespace->members();
    if (! _translationUnit->ast())
        return; // nothing to do.

    if (TranslationUnitAST *ast = _translationUnit->ast()->asTranslationUnit()) {
        for (DeclarationListAST *decl = ast->declaration_list; decl; decl = decl->next) {
            semantic.check(decl->value, globals);
        }
    } else if (ExpressionAST *ast = _translationUnit->ast()->asExpression()) {
        semantic.check(ast, globals);
    }
}

void Document::releaseSource()
{
    _source.clear();
}

void Document::releaseTranslationUnit()
{
    _translationUnit->release();
}

Snapshot::Snapshot()
{
}

Snapshot::~Snapshot()
{
}

int Snapshot::size() const
{
    return _documents.size();
}

bool Snapshot::isEmpty() const
{
    return _documents.isEmpty();
}

Document::Ptr Snapshot::operator[](const QString &fileName) const
{
    return _documents.value(fileName, Document::Ptr());
}

Snapshot::const_iterator Snapshot::find(const QString &fileName) const
{
    return _documents.find(fileName);
}

void Snapshot::remove(const QString &fileName)
{
    _documents.remove(fileName);
}

bool Snapshot::contains(const QString &fileName) const
{
    return _documents.contains(fileName);
}

void Snapshot::insert(Document::Ptr doc)
{
    if (doc)
        _documents.insert(doc->fileName(), doc);
}

QByteArray Snapshot::preprocessedCode(const QString &source, const QString &fileName) const
{
    FastPreprocessor pp(*this);
    return pp.run(fileName, source);
}

Document::Ptr Snapshot::documentFromSource(const QByteArray &preprocessedCode,
                                           const QString &fileName) const
{
    Document::Ptr newDoc = Document::create(fileName);

    if (Document::Ptr thisDocument = document(fileName)) {
        newDoc->_revision = thisDocument->_revision;
        newDoc->_editorRevision = thisDocument->_editorRevision;
        newDoc->_lastModified = thisDocument->_lastModified;
        newDoc->_includes = thisDocument->_includes;
        newDoc->_definedMacros = thisDocument->_definedMacros;
        newDoc->_macroUses = thisDocument->_macroUses;
    }

    newDoc->setSource(preprocessedCode);
    return newDoc;
}

QSharedPointer<NamespaceBinding> Snapshot::globalNamespaceBinding(Document::Ptr doc) const
{
    return CPlusPlus::bind(doc, *this);
}

Document::Ptr Snapshot::document(const QString &fileName) const
{
    return _documents.value(fileName);
}

Snapshot Snapshot::simplified(Document::Ptr doc) const
{
    Snapshot snapshot;
    simplified_helper(doc, &snapshot);
    return snapshot;
}

void Snapshot::simplified_helper(Document::Ptr doc, Snapshot *snapshot) const
{
    if (! doc)
        return;

    if (! snapshot->contains(doc->fileName())) {
        snapshot->insert(doc);

        foreach (const Document::Include &incl, doc->includes()) {
            Document::Ptr includedDoc = document(incl.fileName());
            simplified_helper(includedDoc, snapshot);
        }
    }
}
<commit_msg>Disable C++0x support for now<commit_after>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/

#include "CppDocument.h"
#include "CppBindings.h"
#include "FastPreprocessor.h"

#include <Control.h>
#include <TranslationUnit.h>
#include <DiagnosticClient.h>
#include <Semantic.h>
#include <Literals.h>
#include <Symbols.h>
#include <AST.h>
#include <Scope.h>

#include <QtCore/QByteArray>
#include <QtCore/QBitArray>
#include <QtCore/QDir>
#include <QtCore/QtDebug>

/*!
    \namespace CPlusPlus
    The namespace for C++ related tools.
*/

using namespace CPlusPlus;

namespace {

class DocumentDiagnosticClient : public DiagnosticClient
{
    enum { MAX_MESSAGE_COUNT = 10 };

public:
    DocumentDiagnosticClient(Document *doc, QList<Document::DiagnosticMessage> *messages)
        : doc(doc),
          messages(messages),
          errorCount(0)
    { }

    virtual void report(int level,
                        const StringLiteral *fileId,
                        unsigned line, unsigned column,
                        const char *format, va_list ap)
    {
        if (level == Error) {
            ++errorCount;

            if (errorCount >= MAX_MESSAGE_COUNT)
                return; // ignore the error
        }

        const QString fileName = QString::fromUtf8(fileId->chars(), fileId->size());

        if (fileName != doc->fileName())
            return;

        QString message;
        message.vsprintf(format, ap);

        Document::DiagnosticMessage m(convertLevel(level), doc->fileName(),
                                      line, column, message);
        messages->append(m);
    }

    static int convertLevel(int level) {
        switch (level) {
            case Warning: return Document::DiagnosticMessage::Warning;
            case Error:   return Document::DiagnosticMessage::Error;
            case Fatal:   return Document::DiagnosticMessage::Fatal;
            default:      return Document::DiagnosticMessage::Error;
        }
    }

private:
    Document *doc;
    QList<Document::DiagnosticMessage> *messages;
    int errorCount;
};

} // anonymous namespace

Document::Document(const QString &fileName)
    : _fileName(QDir::cleanPath(fileName)),
      _globalNamespace(0),
      _revision(0),
      _editorRevision(0)
{
    _control = new Control();

    _control->setDiagnosticClient(new DocumentDiagnosticClient(this, &_diagnosticMessages));

    const QByteArray localFileName = fileName.toUtf8();
    const StringLiteral *fileId = _control->findOrInsertStringLiteral(localFileName.constData(),
                                                                      localFileName.size());
    _translationUnit = new TranslationUnit(_control, fileId);
    _translationUnit->setQtMocRunEnabled(true);
    _translationUnit->setCxxOxEnabled(false);
    _translationUnit->setObjCEnabled(true);
    (void) _control->switchTranslationUnit(_translationUnit);
}

Document::~Document()
{
    delete _translationUnit;
    delete _control->diagnosticClient();
    delete _control;
}

Control *Document::control() const
{
    return _control;
}

unsigned Document::revision() const
{
    return _revision;
}

void Document::setRevision(unsigned revision)
{
    _revision = revision;
}

unsigned Document::editorRevision() const
{
    return _editorRevision;
}

void Document::setEditorRevision(unsigned editorRevision)
{
    _editorRevision = editorRevision;
}

QDateTime Document::lastModified() const
{
    return _lastModified;
}

void Document::setLastModified(const QDateTime &lastModified)
{
    _lastModified = lastModified;
}

QString Document::fileName() const
{
    return _fileName;
}

QStringList Document::includedFiles() const
{
    QStringList files;
    foreach (const Include &i, _includes)
        files.append(i.fileName());
    files.removeDuplicates();
    return files;
}

void Document::addIncludeFile(const QString &fileName, unsigned line)
{
    _includes.append(Include(QDir::cleanPath(fileName), line));
}

void Document::appendMacro(const Macro &macro)
{
    _definedMacros.append(macro);
}

void Document::addMacroUse(const Macro &macro, unsigned offset, unsigned length,
                           unsigned beginLine,
                           const QVector<MacroArgumentReference> &actuals, bool inCondition)
{
    MacroUse use(macro, offset, offset + length, beginLine);
    use.setInCondition(inCondition);

    foreach (const MacroArgumentReference &actual, actuals) {
        const Block arg(actual.position(), actual.position() + actual.length());

        use.addArgument(arg);
    }

    _macroUses.append(use);
}

void Document::addUndefinedMacroUse(const QByteArray &name, unsigned offset)
{
    QByteArray copy(name.data(), name.size());
    UndefinedMacroUse use(copy, offset);
    _undefinedMacroUses.append(use);
}

/*!
    \class Document::MacroUse
    \brief Represents the usage of a macro in a \l {Document}.
    \sa Document::UndefinedMacroUse
*/

/*!
    \class Document::UndefinedMacroUse
    \brief Represents a macro that was looked up, but not found.

    Holds data about the reference to a macro in an \tt{#ifdef} or \tt{#ifndef}
    or argument to the \tt{defined} operator inside an \tt{#if} or \tt{#elif} that does
    not exist.

    \sa Document::undefinedMacroUses(), Document::MacroUse, Macro
*/

/*!
    \fn QByteArray Document::UndefinedMacroUse::name() const

    Returns the name of the macro that was not found.
*/

/*!
    \fn QList<UndefinedMacroUse> Document::undefinedMacroUses() const

    Returns a list of referenced but undefined macros.

    \sa Document::macroUses(), Document::definedMacros(), Macro
*/

/*!
    \fn QList<MacroUse> Document::macroUses() const

    Returns a list of macros used.

    \sa Document::undefinedMacroUses(), Document::definedMacros(), Macro
*/

/*!
    \fn QList<Macro> Document::definedMacros() const

    Returns the list of macros defined.

    \sa Document::macroUses(), Document::undefinedMacroUses()
*/

TranslationUnit *Document::translationUnit() const
{
    return _translationUnit;
}

bool Document::skipFunctionBody() const
{
    return _translationUnit->skipFunctionBody();
}

void Document::setSkipFunctionBody(bool skipFunctionBody)
{
    _translationUnit->setSkipFunctionBody(skipFunctionBody);
}

unsigned Document::globalSymbolCount() const
{
    if (! _globalNamespace)
        return 0;

    return _globalNamespace->memberCount();
}

Symbol *Document::globalSymbolAt(unsigned index) const
{
    return _globalNamespace->memberAt(index);
}

Scope *Document::globalSymbols() const
{
    if (! _globalNamespace)
        return 0;

    return _globalNamespace->members();
}

Namespace *Document::globalNamespace() const
{
    return _globalNamespace;
}

void Document::setGlobalNamespace(Namespace *globalNamespace)
{
    _globalNamespace = globalNamespace;
}

Symbol *Document::findSymbolAt(unsigned line, unsigned column) const
{
    return findSymbolAt(line, column, globalSymbols());
}

Symbol *Document::findSymbolAt(unsigned line, unsigned column, Scope *scope) const
{
    Symbol *previousSymbol = 0;

    for (unsigned i = 0; i < scope->symbolCount(); ++i) {
        Symbol *symbol = scope->symbolAt(i);
        if (symbol->line() > line)
            break;

        previousSymbol = symbol;
    }

    if (previousSymbol) {
        if (ScopedSymbol *scoped = previousSymbol->asScopedSymbol()) {
            if (Symbol *member = findSymbolAt(line, column, scoped->members()))
                return member;
        }
    }

    return previousSymbol;
}

const Macro *Document::findMacroDefinitionAt(unsigned line) const
{
    foreach (const Macro &macro, _definedMacros) {
        if (macro.line() == line)
            return &macro;
    }
    return 0;
}

const Document::MacroUse *Document::findMacroUseAt(unsigned offset) const
{
    foreach (const Document::MacroUse &use, _macroUses) {
        if (use.contains(offset))
            return &use;
    }
    return 0;
}

const Document::UndefinedMacroUse *Document::findUndefinedMacroUseAt(unsigned offset) const
{
    foreach (const Document::UndefinedMacroUse &use, _undefinedMacroUses) {
        if (use.contains(offset))
            return &use;
    }
    return 0;
}

Document::Ptr Document::create(const QString &fileName)
{
    Document::Ptr doc(new Document(fileName));
    return doc;
}

QByteArray Document::source() const
{ return _source; }

void Document::setSource(const QByteArray &source)
{
    _source = source;
    _translationUnit->setSource(_source.constBegin(), _source.size());
}

void Document::startSkippingBlocks(unsigned start)
{
    _skippedBlocks.append(Block(start, 0));
}

void Document::stopSkippingBlocks(unsigned stop)
{
    if (_skippedBlocks.isEmpty())
        return;

    unsigned start = _skippedBlocks.back().begin();
    if (start > stop)
        _skippedBlocks.removeLast(); // Ignore this block, it's invalid.
    else
        _skippedBlocks.back() = Block(start, stop);
}

bool Document::isTokenized() const
{
    return _translationUnit->isTokenized();
}

void Document::tokenize()
{
    _translationUnit->tokenize();
}

bool Document::isParsed() const
{
    return _translationUnit->isParsed();
}

bool Document::parse(ParseMode mode)
{
    TranslationUnit::ParseMode m = TranslationUnit::ParseTranlationUnit;
    switch (mode) {
    case ParseTranlationUnit:
        m = TranslationUnit::ParseTranlationUnit;
        break;

    case ParseDeclaration:
        m = TranslationUnit::ParseDeclaration;
        break;

    case ParseExpression:
        m = TranslationUnit::ParseExpression;
        break;

    case ParseDeclarator:
        m = TranslationUnit::ParseDeclarator;
        break;

    case ParseStatement:
        m = TranslationUnit::ParseStatement;
        break;

    default:
        break;
    }

    return _translationUnit->parse(m);
}

void Document::check(CheckMode mode)
{
    Q_ASSERT(!_globalNamespace);

    if (! isParsed())
        parse();

    Semantic semantic(_translationUnit);
    if (mode == FastCheck)
        semantic.setSkipFunctionBodies(true);

    _globalNamespace = _control->newNamespace(0);
    Scope *globals = _globalNamespace->members();
    if (! _translationUnit->ast())
        return; // nothing to do.

    if (TranslationUnitAST *ast = _translationUnit->ast()->asTranslationUnit()) {
        for (DeclarationListAST *decl = ast->declaration_list; decl; decl = decl->next) {
            semantic.check(decl->value, globals);
        }
    } else if (ExpressionAST *ast = _translationUnit->ast()->asExpression()) {
        semantic.check(ast, globals);
    }
}

void Document::releaseSource()
{
    _source.clear();
}

void Document::releaseTranslationUnit()
{
    _translationUnit->release();
}

Snapshot::Snapshot()
{
}

Snapshot::~Snapshot()
{
}

int Snapshot::size() const
{
    return _documents.size();
}

bool Snapshot::isEmpty() const
{
    return _documents.isEmpty();
}

Document::Ptr Snapshot::operator[](const QString &fileName) const
{
    return _documents.value(fileName, Document::Ptr());
}

Snapshot::const_iterator Snapshot::find(const QString &fileName) const
{
    return _documents.find(fileName);
}

void Snapshot::remove(const QString &fileName)
{
    _documents.remove(fileName);
}

bool Snapshot::contains(const QString &fileName) const
{
    return _documents.contains(fileName);
}

void Snapshot::insert(Document::Ptr doc)
{
    if (doc)
        _documents.insert(doc->fileName(), doc);
}

QByteArray Snapshot::preprocessedCode(const QString &source, const QString &fileName) const
{
    FastPreprocessor pp(*this);
    return pp.run(fileName, source);
}

Document::Ptr Snapshot::documentFromSource(const QByteArray &preprocessedCode,
                                           const QString &fileName) const
{
    Document::Ptr newDoc = Document::create(fileName);

    if (Document::Ptr thisDocument = document(fileName)) {
        newDoc->_revision = thisDocument->_revision;
        newDoc->_editorRevision = thisDocument->_editorRevision;
        newDoc->_lastModified = thisDocument->_lastModified;
        newDoc->_includes = thisDocument->_includes;
        newDoc->_definedMacros = thisDocument->_definedMacros;
        newDoc->_macroUses = thisDocument->_macroUses;
    }

    newDoc->setSource(preprocessedCode);
    return newDoc;
}

QSharedPointer<NamespaceBinding> Snapshot::globalNamespaceBinding(Document::Ptr doc) const
{
    return CPlusPlus::bind(doc, *this);
}

Document::Ptr Snapshot::document(const QString &fileName) const
{
    return _documents.value(fileName);
}

Snapshot Snapshot::simplified(Document::Ptr doc) const
{
    Snapshot snapshot;
    simplified_helper(doc, &snapshot);
    return snapshot;
}

void Snapshot::simplified_helper(Document::Ptr doc, Snapshot *snapshot) const
{
    if (! doc)
        return;

    if (! snapshot->contains(doc->fileName())) {
        snapshot->insert(doc);

        foreach (const Document::Include &incl, doc->includes()) {
            Document::Ptr includedDoc = document(incl.fileName());
            simplified_helper(includedDoc, snapshot);
        }
    }
}
<|endoftext|>


<commit_before>// Sleep

#include <chrono>
#include <thread>

int main()
{
	std::chrono::milliseconds sleepDuration(20);

	std::this_thread::sleep_for(sleepDuration);
}

// Block the execution of a thread for a given amount of time.
//
// On [8], we create a [`std::chrono::milliseconds`](cpp/chrono/duration)
// object representing the number of milliseconds to sleep ([other
// duration units](cpp/chrono/duration#Helper_types) may also be used).
// On [10], the call to [`std::this_thread::sleep_for`](cpp/thread/sleep_for)
// will block the execution of the current thread for at least the
// given duration.

<commit_msg>Remove link from sleep sample<commit_after>// Sleep

#include <chrono>
#include <thread>

int main()
{
	std::chrono::milliseconds sleepDuration(20);

	std::this_thread::sleep_for(sleepDuration);
}

// Block the execution of a thread for a given amount of time.
//
// On [8], we create a [`std::chrono::milliseconds`](cpp/chrono/duration)
// object representing the number of milliseconds to sleep (other
// duration units may also be used). On [10], the call to
// [`std::this_thread::sleep_for`](cpp/thread/sleep_for) will block
// the execution of the current thread for at least the given
// duration.

<|endoftext|>


<commit_before>#include <unistd.h>
#include <cassert>
#include <boost/shared_ptr.hpp>

#include "gen-cpp/DataHub.h"
#include <thrift/transport/THttpClient.h>
#include <thrift/transport/TBufferTransports.h>
#include <thrift/protocol/TBinaryProtocol.h>

/**
 * Sample DataHub C++ Client
 *
 * @author anantb
 * @date 11/07/2013
 *
 */

using namespace std;
using namespace boost;
using namespace apache::thrift;
using namespace apache::thrift::protocol;
using namespace apache::thrift::transport;

using namespace datahub;

int main () {
  try {
    shared_ptr<THttpClient> transport(new THttpClient("datahub.csail.mit.edu", 80, "/service"));
    shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));
    DataHubClient client(protocol);

    transport->open();
    double version = client.get_version();
    cout << version << endl;

    // XXX: does not work if we directly set user/password
    DHConnectionParams params;
    params.__set_user("anantb");
    params.__set_password("anant");

    DHConnection conn;
    client.connect(conn, params);
    cout << conn.user << endl;

    DHQueryResult res;
    client.execute_sql(res, conn, "select * from anantb.demo.team", vector<string>());
    assert( !res.data.table.rows.size() >= 1 );
    cout << res.data.table.rows[1].cells[0].value << endl;

    transport->close();
  } catch (TException &tx) {
    cout << "ERROR: " << tx.what();
  }

  return 0;
}
<commit_msg>fixed C++ client<commit_after>#include <unistd.h>
#include <cassert>
#include <boost/shared_ptr.hpp>

#include "gen-cpp/DataHub.h"
#include <thrift/transport/THttpClient.h>
#include <thrift/transport/TBufferTransports.h>
#include <thrift/protocol/TBinaryProtocol.h>

/**
 * Sample DataHub C++ Client
 *
 * @author anantb
 * @author stephentu
 * @date 11/07/2013
 *
 */

using namespace std;
using namespace boost;
using namespace apache::thrift;
using namespace apache::thrift::protocol;
using namespace apache::thrift::transport;

using namespace datahub;

int main () {
  try {
    shared_ptr<THttpClient> transport(new THttpClient("datahub.csail.mit.edu", 80, "/service"));
    shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));
    DataHubClient client(protocol);

    transport->open();
    double version = client.get_version();
    cout << version << endl;

    DHConnectionParams params = DHConnectionParams();
    params.__set_user("anantb");
    params.__set_password("anant");

    DHConnection conn;
    client.connect(conn, params);

    DHQueryResult res;
    client.execute_sql(res, conn, "select * from anantb.demo.team", vector<string>());
    for(vector<DHRow>::iterator row_it = res.data.table.rows.begin(); row_it != res.data.table.rows.end(); ++row_it) {
      for(vector<DHCell>::iterator cell_it = (*row_it).cells.begin(); cell_it != (*row_it).cells.end(); ++cell_it) {
    	cout << (*cell_it).value << "\t";
      }
      cout << "\n";
    }

    transport->close();
  } catch (TException &tx) {
    cout << "ERROR: " << tx.what();
  }

  return 0;
}
<|endoftext|>


<commit_before>// Copyright 2014 MongoDB Inc.
//
// 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 "catch.hpp"
#include "helpers.hpp"

#include <bsoncxx/stdx/string_view.hpp>
#include <mongocxx/read_concern.hpp>
#include <mongocxx/stdx.hpp>

using namespace mongocxx;

TEST_CASE("a default read_concern", "[read_concern]") {
    read_concern rc{};

    SECTION("has level k_server_default") {
        REQUIRE(rc.acknowledge_level() == read_concern::level::k_server_default);
    }

    SECTION("has an empty string") {
        REQUIRE(rc.acknowledge_string() == "");
    }
}

TEST_CASE("read_concern fields may be set and retrieved", "[read_concern]") {
    read_concern rc{};

    REQUIRE_NOTHROW(rc.acknowledge_level(read_concern::level::k_majority));
    REQUIRE(rc.acknowledge_level() == read_concern::level::k_majority);

    REQUIRE_NOTHROW(rc.acknowledge_string(stdx::string_view{"local"}));
    REQUIRE(rc.acknowledge_string() == stdx::string_view{"local"});
}

TEST_CASE("read_concern level and string affect each other", "[read_concern]") {
    read_concern rc{};

    SECTION("setting the level changes the string") {
        rc.acknowledge_level(read_concern::level::k_local);
        REQUIRE(rc.acknowledge_string() == stdx::string_view{"local"});
    }

    SECTION("setting the string changes the level") {
        rc.acknowledge_string("majority");
        REQUIRE(rc.acknowledge_level() == read_concern::level::k_majority);
    }

    SECTION("setting the string to an unknown value changes the level to unknown") {
        rc.acknowledge_string("futureCompatible");
        REQUIRE(rc.acknowledge_level() == read_concern::level::k_unknown);
    }
}

TEST_CASE("read_concern throws when trying to set level to k_unknown", "[read_concern]") {
    read_concern rc{};

    REQUIRE_THROWS(rc.acknowledge_level(read_concern::level::k_unknown));
}
<commit_msg>minor: fixup compile<commit_after>// Copyright 2014 MongoDB Inc.
//
// 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 "catch.hpp"
#include "helpers.hpp"

#include <bsoncxx/stdx/string_view.hpp>
#include <mongocxx/read_concern.hpp>
#include <mongocxx/stdx.hpp>

using namespace mongocxx;

TEST_CASE("a default read_concern", "[read_concern]") {
    read_concern rc{};

    SECTION("has level k_server_default") {
        REQUIRE(rc.acknowledge_level() == read_concern::level::k_server_default);
    }

    SECTION("has an empty string") {
        REQUIRE(rc.acknowledge_string() == stdx::string_view{""});
    }
}

TEST_CASE("read_concern fields may be set and retrieved", "[read_concern]") {
    read_concern rc{};

    REQUIRE_NOTHROW(rc.acknowledge_level(read_concern::level::k_majority));
    REQUIRE(rc.acknowledge_level() == read_concern::level::k_majority);

    REQUIRE_NOTHROW(rc.acknowledge_string(stdx::string_view{"local"}));
    REQUIRE(rc.acknowledge_string() == stdx::string_view{"local"});
}

TEST_CASE("read_concern level and string affect each other", "[read_concern]") {
    read_concern rc{};

    SECTION("setting the level changes the string") {
        rc.acknowledge_level(read_concern::level::k_local);
        REQUIRE(rc.acknowledge_string() == stdx::string_view{"local"});
    }

    SECTION("setting the string changes the level") {
        rc.acknowledge_string("majority");
        REQUIRE(rc.acknowledge_level() == read_concern::level::k_majority);
    }

    SECTION("setting the string to an unknown value changes the level to unknown") {
        rc.acknowledge_string("futureCompatible");
        REQUIRE(rc.acknowledge_level() == read_concern::level::k_unknown);
    }
}

TEST_CASE("read_concern throws when trying to set level to k_unknown", "[read_concern]") {
    read_concern rc{};

    REQUIRE_THROWS(rc.acknowledge_level(read_concern::level::k_unknown));
}
<|endoftext|>