<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkAnimationScene.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/

#include "vtkAnimationScene.h"
#include "vtkObjectFactory.h"
#include "vtkCollection.h"
#include "vtkCollectionIterator.h"
#include "vtkTimerLog.h"

vtkCxxRevisionMacro(vtkAnimationScene, "1.4");
vtkStandardNewMacro(vtkAnimationScene);

//----------------------------------------------------------------------------
vtkAnimationScene::vtkAnimationScene()
{
  this->PlayMode = VTK_ANIMATION_SCENE_PLAYMODE_SEQUENCE;
  this->FrameRate = 10.0;
  this->Loop = 0;
  this->InPlay = 0;
  this->StopPlay = 0;
  this->CurrentTime = 0.0;

  this->AnimationCues = vtkCollection::New();
  this->AnimationCuesIterator = this->AnimationCues->NewIterator();
  this->AnimationTimer = vtkTimerLog::New();
}

//----------------------------------------------------------------------------
vtkAnimationScene::~vtkAnimationScene()
{
  if (this->InPlay)
    {
    this->Stop();
    }
  this->AnimationCues->Delete();
  this->AnimationCuesIterator->Delete();
  this->AnimationTimer->Delete();
}

//----------------------------------------------------------------------------
void vtkAnimationScene::AddCue(vtkAnimationCue* cue)
{
  if (this->AnimationCues->IsItemPresent(cue))
    {
    vtkErrorMacro("Animation cue already present in the scene");
    return;
    }
  if (this->TimeMode == VTK_ANIMATION_CUE_TIMEMODE_NORMALIZED &&
    cue->GetTimeMode() != VTK_ANIMATION_CUE_TIMEMODE_NORMALIZED)
    {
    vtkErrorMacro("A cue with relative time mode cannot be added to a scene "
      "with normalized time mode.");
    return;
    }
  this->AnimationCues->AddItem(cue);
}

//----------------------------------------------------------------------------
void vtkAnimationScene::RemoveCue(vtkAnimationCue* cue)
{
  this->AnimationCues->RemoveItem(cue);
}

//----------------------------------------------------------------------------
void vtkAnimationScene::SetTimeMode(int mode)
{
  if (mode == VTK_ANIMATION_CUE_TIMEMODE_NORMALIZED)
    {
    // If noralized time mode is being set on the scene,
    // ensure that none of the contained cues need relative times.
    vtkCollectionIterator *it = this->AnimationCuesIterator;
    for (it->InitTraversal(); !it->IsDoneWithTraversal(); it->GoToNextItem())
      {
      vtkAnimationCue* cue =
        vtkAnimationCue::SafeDownCast(it->GetCurrentObject());
      if (cue && cue->GetTimeMode() != VTK_ANIMATION_CUE_TIMEMODE_NORMALIZED)
        {
        vtkErrorMacro("Scene contains a cue in relative mode. It must be removed "
          "or chaged to normalized mode before changing the scene time mode");
        return;
        }
      }
    }
  this->Superclass::SetTimeMode(mode);
}

//----------------------------------------------------------------------------
void vtkAnimationScene::InitializeChildren()
{
  // run thr all the cues and init them.
  vtkCollectionIterator *it = this->AnimationCuesIterator;
  for (it->InitTraversal(); !it->IsDoneWithTraversal(); it->GoToNextItem())
    {
    vtkAnimationCue* cue =
      vtkAnimationCue::SafeDownCast(it->GetCurrentObject());
    if (cue)
      {
      cue->Initialize();
      }
    }
}

//----------------------------------------------------------------------------
void vtkAnimationScene::FinalizeChildren()
{
  vtkCollectionIterator *it = this->AnimationCuesIterator;
  for (it->InitTraversal(); !it->IsDoneWithTraversal(); it->GoToNextItem())
    {
    vtkAnimationCue* cue =
      vtkAnimationCue::SafeDownCast(it->GetCurrentObject());
    if (cue)
      {
      cue->Finalize();
      }
    }
}

//----------------------------------------------------------------------------
void vtkAnimationScene::Play()
{
  cout << "LOOP: " << this->Loop << endl;
  if (this->InPlay)
    {
    return;
    }

  if (this->TimeMode == VTK_ANIMATION_CUE_TIMEMODE_NORMALIZED)
    {
    vtkErrorMacro("Cannot play a scene with normalized time mode");
    return;
    }
  if (this->EndTime <= this->StartTime)
    {
    vtkErrorMacro("Scene start and end times are not suitable for playing");
    return;
    }

  this->InPlay = 1;
  this->StopPlay = 0;
  this->FrameRate = (!this->FrameRate)? 1.0 : this->FrameRate;
  // the actual play loop, check for StopPlay flag.
  double deltatime = 0.0;
  double currenttime = this->CurrentTime;
  double span = this->EndTime - this->StartTime;

  // adjust currenttime to a valid time.
  currenttime = (currenttime < this->StartTime || currenttime >= this->EndTime)?
    this->StartTime : currenttime;
  double clocktime = currenttime;
  double oldclocktime = clocktime;
  double time_adjustment = 0;
  this->AnimationTimer->StartTimer();
  do
    {
    this->Initialize(); // Set the Scene in unintialized mode.
    do
      {
      currenttime = clocktime - time_adjustment;
      this->Tick(currenttime, deltatime);
      oldclocktime = clocktime;
      if (this->PlayMode == VTK_ANIMATION_SCENE_PLAYMODE_REALTIME)
        {
        this->AnimationTimer->StopTimer();
        clocktime = this->AnimationTimer->GetElapsedTime() +
          this->StartTime;
        }
      else if (this->PlayMode == VTK_ANIMATION_SCENE_PLAYMODE_SEQUENCE)
        {
        clocktime += 1.0 / this->FrameRate;
        }
      else
        {
        vtkErrorMacro("Invalid Play Mode");
        this->StopPlay = 1;
        break;
        }
      deltatime = clocktime - oldclocktime;
      deltatime = (deltatime < 0)? -1*deltatime : deltatime;
      }
    while (!this->StopPlay && this->CueState != vtkAnimationCue::INACTIVE);
    time_adjustment += span;
    }
  while (this->Loop && !this->StopPlay);
  this->StopPlay = 0;
  this->InPlay = 0;
}

//----------------------------------------------------------------------------
void vtkAnimationScene::Stop()
{
  if (!this->InPlay)
    {
    return;
    }
  this->StopPlay = 1;
}

//----------------------------------------------------------------------------
void vtkAnimationScene::TickInternal(double currenttime, double deltatime)
{
  this->CurrentTime = currenttime;

  vtkCollectionIterator* iter = this->AnimationCuesIterator;
  for (iter->InitTraversal(); !iter->IsDoneWithTraversal(); iter->GoToNextItem())
    {
    vtkAnimationCue* cue = vtkAnimationCue::SafeDownCast(
      iter->GetCurrentObject());
    if (cue)
      {
      switch(cue->GetTimeMode())
        {
      case VTK_ANIMATION_CUE_TIMEMODE_RELATIVE:
        cue->Tick(currenttime - this->StartTime, deltatime);
        break;
      case VTK_ANIMATION_CUE_TIMEMODE_NORMALIZED:
        cue->Tick( (currenttime - this->StartTime) / (this->EndTime - this->StartTime),
          deltatime / (this->EndTime - this->StartTime));
        break;
      default:
        vtkErrorMacro("Invalid cue time mode");
        }
      }
    }
  this->Superclass::TickInternal(currenttime, deltatime);
}

//----------------------------------------------------------------------------
void vtkAnimationScene::StartCueInternal()
{
  this->Superclass::StartCueInternal();
  this->InitializeChildren();
}

//----------------------------------------------------------------------------
void vtkAnimationScene::EndCueInternal()
{
  this->FinalizeChildren();
  this->Superclass::EndCueInternal();
}

//----------------------------------------------------------------------------
void vtkAnimationScene::SetCurrentTime(double currenttime)
{
  if (this->InPlay)
    {
    vtkErrorMacro("SetCurrentTime cannot be called while playing");
    return;
    }
  this->Initialize();
  this->Tick(currenttime,0.0);
  if (this->CueState == vtkAnimationCue::INACTIVE)
    {
    this->Finalize();
    }
}

//----------------------------------------------------------------------------
void vtkAnimationScene::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
  os << indent << "PlayMode: " << this->PlayMode << endl;
  os << indent << "FrameRate: " << this->FrameRate << endl;
  os << indent << "Loop: " << this->Loop << endl;
  os << indent << "InPlay: " << this->InPlay << endl;
  os << indent << "StopPlay: " << this->StopPlay << endl;
  os << indent << "CurrentTime: " << this->CurrentTime << endl;
}
<commit_msg>STYLE: removed debug couts<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkAnimationScene.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/

#include "vtkAnimationScene.h"
#include "vtkObjectFactory.h"
#include "vtkCollection.h"
#include "vtkCollectionIterator.h"
#include "vtkTimerLog.h"

vtkCxxRevisionMacro(vtkAnimationScene, "1.5");
vtkStandardNewMacro(vtkAnimationScene);

//----------------------------------------------------------------------------
vtkAnimationScene::vtkAnimationScene()
{
  this->PlayMode = VTK_ANIMATION_SCENE_PLAYMODE_SEQUENCE;
  this->FrameRate = 10.0;
  this->Loop = 0;
  this->InPlay = 0;
  this->StopPlay = 0;
  this->CurrentTime = 0.0;

  this->AnimationCues = vtkCollection::New();
  this->AnimationCuesIterator = this->AnimationCues->NewIterator();
  this->AnimationTimer = vtkTimerLog::New();
}

//----------------------------------------------------------------------------
vtkAnimationScene::~vtkAnimationScene()
{
  if (this->InPlay)
    {
    this->Stop();
    }
  this->AnimationCues->Delete();
  this->AnimationCuesIterator->Delete();
  this->AnimationTimer->Delete();
}

//----------------------------------------------------------------------------
void vtkAnimationScene::AddCue(vtkAnimationCue* cue)
{
  if (this->AnimationCues->IsItemPresent(cue))
    {
    vtkErrorMacro("Animation cue already present in the scene");
    return;
    }
  if (this->TimeMode == VTK_ANIMATION_CUE_TIMEMODE_NORMALIZED &&
    cue->GetTimeMode() != VTK_ANIMATION_CUE_TIMEMODE_NORMALIZED)
    {
    vtkErrorMacro("A cue with relative time mode cannot be added to a scene "
      "with normalized time mode.");
    return;
    }
  this->AnimationCues->AddItem(cue);
}

//----------------------------------------------------------------------------
void vtkAnimationScene::RemoveCue(vtkAnimationCue* cue)
{
  this->AnimationCues->RemoveItem(cue);
}

//----------------------------------------------------------------------------
void vtkAnimationScene::SetTimeMode(int mode)
{
  if (mode == VTK_ANIMATION_CUE_TIMEMODE_NORMALIZED)
    {
    // If noralized time mode is being set on the scene,
    // ensure that none of the contained cues need relative times.
    vtkCollectionIterator *it = this->AnimationCuesIterator;
    for (it->InitTraversal(); !it->IsDoneWithTraversal(); it->GoToNextItem())
      {
      vtkAnimationCue* cue =
        vtkAnimationCue::SafeDownCast(it->GetCurrentObject());
      if (cue && cue->GetTimeMode() != VTK_ANIMATION_CUE_TIMEMODE_NORMALIZED)
        {
        vtkErrorMacro("Scene contains a cue in relative mode. It must be removed "
          "or chaged to normalized mode before changing the scene time mode");
        return;
        }
      }
    }
  this->Superclass::SetTimeMode(mode);
}

//----------------------------------------------------------------------------
void vtkAnimationScene::InitializeChildren()
{
  // run thr all the cues and init them.
  vtkCollectionIterator *it = this->AnimationCuesIterator;
  for (it->InitTraversal(); !it->IsDoneWithTraversal(); it->GoToNextItem())
    {
    vtkAnimationCue* cue =
      vtkAnimationCue::SafeDownCast(it->GetCurrentObject());
    if (cue)
      {
      cue->Initialize();
      }
    }
}

//----------------------------------------------------------------------------
void vtkAnimationScene::FinalizeChildren()
{
  vtkCollectionIterator *it = this->AnimationCuesIterator;
  for (it->InitTraversal(); !it->IsDoneWithTraversal(); it->GoToNextItem())
    {
    vtkAnimationCue* cue =
      vtkAnimationCue::SafeDownCast(it->GetCurrentObject());
    if (cue)
      {
      cue->Finalize();
      }
    }
}

//----------------------------------------------------------------------------
void vtkAnimationScene::Play()
{
  if (this->InPlay)
    {
    return;
    }

  if (this->TimeMode == VTK_ANIMATION_CUE_TIMEMODE_NORMALIZED)
    {
    vtkErrorMacro("Cannot play a scene with normalized time mode");
    return;
    }
  if (this->EndTime <= this->StartTime)
    {
    vtkErrorMacro("Scene start and end times are not suitable for playing");
    return;
    }

  this->InPlay = 1;
  this->StopPlay = 0;
  this->FrameRate = (!this->FrameRate)? 1.0 : this->FrameRate;
  // the actual play loop, check for StopPlay flag.
  double deltatime = 0.0;
  double currenttime = this->CurrentTime;
  double span = this->EndTime - this->StartTime;

  // adjust currenttime to a valid time.
  currenttime = (currenttime < this->StartTime || currenttime >= this->EndTime)?
    this->StartTime : currenttime;
  double clocktime = currenttime;
  double oldclocktime = clocktime;
  double time_adjustment = 0;
  this->AnimationTimer->StartTimer();
  do
    {
    this->Initialize(); // Set the Scene in unintialized mode.
    do
      {
      currenttime = clocktime - time_adjustment;
      this->Tick(currenttime, deltatime);
      oldclocktime = clocktime;
      if (this->PlayMode == VTK_ANIMATION_SCENE_PLAYMODE_REALTIME)
        {
        this->AnimationTimer->StopTimer();
        clocktime = this->AnimationTimer->GetElapsedTime() +
          this->StartTime;
        }
      else if (this->PlayMode == VTK_ANIMATION_SCENE_PLAYMODE_SEQUENCE)
        {
        clocktime += 1.0 / this->FrameRate;
        }
      else
        {
        vtkErrorMacro("Invalid Play Mode");
        this->StopPlay = 1;
        break;
        }
      deltatime = clocktime - oldclocktime;
      deltatime = (deltatime < 0)? -1*deltatime : deltatime;
      }
    while (!this->StopPlay && this->CueState != vtkAnimationCue::INACTIVE);
    time_adjustment += span;
    }
  while (this->Loop && !this->StopPlay);
  this->StopPlay = 0;
  this->InPlay = 0;
}

//----------------------------------------------------------------------------
void vtkAnimationScene::Stop()
{
  if (!this->InPlay)
    {
    return;
    }
  this->StopPlay = 1;
}

//----------------------------------------------------------------------------
void vtkAnimationScene::TickInternal(double currenttime, double deltatime)
{
  this->CurrentTime = currenttime;

  vtkCollectionIterator* iter = this->AnimationCuesIterator;
  for (iter->InitTraversal(); !iter->IsDoneWithTraversal(); iter->GoToNextItem())
    {
    vtkAnimationCue* cue = vtkAnimationCue::SafeDownCast(
      iter->GetCurrentObject());
    if (cue)
      {
      switch(cue->GetTimeMode())
        {
      case VTK_ANIMATION_CUE_TIMEMODE_RELATIVE:
        cue->Tick(currenttime - this->StartTime, deltatime);
        break;
      case VTK_ANIMATION_CUE_TIMEMODE_NORMALIZED:
        cue->Tick( (currenttime - this->StartTime) / (this->EndTime - this->StartTime),
          deltatime / (this->EndTime - this->StartTime));
        break;
      default:
        vtkErrorMacro("Invalid cue time mode");
        }
      }
    }
  this->Superclass::TickInternal(currenttime, deltatime);
}

//----------------------------------------------------------------------------
void vtkAnimationScene::StartCueInternal()
{
  this->Superclass::StartCueInternal();
  this->InitializeChildren();
}

//----------------------------------------------------------------------------
void vtkAnimationScene::EndCueInternal()
{
  this->FinalizeChildren();
  this->Superclass::EndCueInternal();
}

//----------------------------------------------------------------------------
void vtkAnimationScene::SetCurrentTime(double currenttime)
{
  if (this->InPlay)
    {
    vtkErrorMacro("SetCurrentTime cannot be called while playing");
    return;
    }
  this->Initialize();
  this->Tick(currenttime,0.0);
  if (this->CueState == vtkAnimationCue::INACTIVE)
    {
    this->Finalize();
    }
}

//----------------------------------------------------------------------------
void vtkAnimationScene::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
  os << indent << "PlayMode: " << this->PlayMode << endl;
  os << indent << "FrameRate: " << this->FrameRate << endl;
  os << indent << "Loop: " << this->Loop << endl;
  os << indent << "InPlay: " << this->InPlay << endl;
  os << indent << "StopPlay: " << this->StopPlay << endl;
  os << indent << "CurrentTime: " << this->CurrentTime << endl;
}
<|endoftext|>


<commit_before>/**
 ******************************************************************************
 * Xenia : Xbox 360 Emulator Research Project                                 *
 ******************************************************************************
 * Copyright 2013 Ben Vanik. All rights reserved.                             *
 * Released under the BSD license - see LICENSE in the root for more details. *
 ******************************************************************************
 */

#include "xenia/base/logging.h"

#include <gflags/gflags.h>

#include <atomic>
#include <cinttypes>
#include <cstdarg>
#include <mutex>
#include <vector>

#include "xenia/base/filesystem.h"
#include "xenia/base/main.h"
#include "xenia/base/math.h"
#include "xenia/base/ring_buffer.h"
#include "xenia/base/threading.h"

// For MessageBox:
// TODO(benvanik): generic API? logging_win.cc?
#if XE_PLATFORM_WIN32
#include "xenia/base/platform_win.h"
#endif  // XE_PLATFORM_WIN32

DEFINE_string(log_file, "",
              "Logs are written to the given file instead of the default.");
DEFINE_bool(flush_log, true, "Flush log file after each log line batch.");

namespace xe {

class Logger;

Logger* logger_ = nullptr;
thread_local std::vector<char> log_format_buffer_(64 * 1024);

class Logger {
 public:
  Logger(const std::wstring& app_name)
      : ring_buffer_(buffer_, kBufferSize), running_(true) {
    if (!FLAGS_log_file.empty()) {
      auto file_path = xe::to_wstring(FLAGS_log_file.c_str());
      xe::filesystem::CreateParentFolder(file_path);
      file_ = xe::filesystem::OpenFile(file_path, "wt");
    } else {
      auto file_path = app_name + L".log";
      file_ = xe::filesystem::OpenFile(file_path, "wt");
    }

    flush_event_ = xe::threading::Event::CreateAutoResetEvent(false);
    write_thread_ =
        xe::threading::Thread::Create({}, [this]() { WriteThread(); });
    write_thread_->set_name("xe::FileLogSink Writer");
  }

  ~Logger() {
    running_ = false;
    flush_event_->Set();
    xe::threading::Wait(write_thread_.get(), true);
    fflush(file_);
    fclose(file_);
  }

  void AppendLine(uint32_t thread_id, const char level_char, const char* buffer,
                  size_t buffer_length) {
    LogLine line;
    line.thread_id = thread_id;
    line.level_char = level_char;
    line.buffer_length = buffer_length;
    while (true) {
      mutex_.lock();
      if (ring_buffer_.write_count() < sizeof(line) + buffer_length) {
        // Buffer is full. Stall.
        mutex_.unlock();
        xe::threading::MaybeYield();
        continue;
      }
      ring_buffer_.Write(&line, sizeof(LogLine));
      ring_buffer_.Write(buffer, buffer_length);
      mutex_.unlock();
      break;
    }
    flush_event_->Set();
  }

 private:
  static const size_t kBufferSize = 32 * 1024 * 1024;

  struct LogLine {
    uint32_t thread_id;
    char level_char;
    size_t buffer_length;
  };

  void WriteThread() {
    while (running_) {
      mutex_.lock();
      bool did_write = false;
      while (!ring_buffer_.empty()) {
        did_write = true;

        // Read line header and write out the line prefix.
        LogLine line;
        ring_buffer_.Read(&line, sizeof(line));
        char prefix[] = {
            line.level_char,
            '>',
            ' ',
            '0',  // Thread ID gets placed here (8 chars).
            '0',
            '0',
            '0',
            '0',
            '0',
            '0',
            '0',
            ' ',
            0,
        };
        std::snprintf(prefix + 3, sizeof(prefix) - 3, "%08" PRIX32 " ",
                      line.thread_id);
        fwrite(prefix, 1, sizeof(prefix) - 1, file_);

        // Get access to the line data - which may be split in the ring buffer -
        // and write it out in parts.
        auto line_range = ring_buffer_.BeginRead(line.buffer_length);
        fwrite(line_range.first, 1, line_range.first_length, file_);
        if (line_range.second_length) {
          fwrite(line_range.second, 1, line_range.second_length, file_);
        }
        // Always ensure there is a newline.
        char last_char = line_range.second
                             ? line_range.second[line_range.second_length - 1]
                             : line_range.first[line_range.first_length - 1];
        if (last_char != '\n') {
          const char suffix[1] = {'\n'};
          fwrite(suffix, 1, sizeof(suffix), file_);
        }
        ring_buffer_.EndRead(std::move(line_range));
      }
      mutex_.unlock();
      if (did_write) {
        if (FLAGS_flush_log) {
          fflush(file_);
        }
      }
      xe::threading::Wait(flush_event_.get(), true);
    }
  }

  FILE* file_ = nullptr;
  uint8_t buffer_[kBufferSize];
  RingBuffer ring_buffer_;
  std::mutex mutex_;
  std::atomic<bool> running_;
  std::unique_ptr<xe::threading::Event> flush_event_;
  std::unique_ptr<xe::threading::Thread> write_thread_;
};

void InitializeLogging(const std::wstring& app_name) {
  // We leak this intentionally - lots of cleanup code needs it.
  logger_ = new Logger(app_name);
}

void LogLineFormat(const char level_char, const char* fmt, ...) {
  va_list args;
  va_start(args, fmt);
  size_t chars_written = vsnprintf(log_format_buffer_.data(),
                                   log_format_buffer_.capacity(), fmt, args);
  va_end(args);
  if (chars_written != std::string::npos) {
    logger_->AppendLine(xe::threading::current_thread_id(), level_char,
                        log_format_buffer_.data(), chars_written);
  } else {
    logger_->AppendLine(xe::threading::current_thread_id(), level_char, fmt,
                        std::strlen(fmt));
  }
}

void LogLineVarargs(const char level_char, const char* fmt, va_list args) {
  size_t chars_written = vsnprintf(log_format_buffer_.data(),
                                   log_format_buffer_.capacity(), fmt, args);
  logger_->AppendLine(xe::threading::current_thread_id(), level_char,
                      log_format_buffer_.data(), chars_written);
}

void LogLine(const char level_char, const char* str, size_t str_length) {
  logger_->AppendLine(
      xe::threading::current_thread_id(), level_char, str,
      str_length == std::string::npos ? std::strlen(str) : str_length);
}

void LogLine(const char level_char, const std::string& str) {
  logger_->AppendLine(xe::threading::current_thread_id(), level_char,
                      str.c_str(), str.length());
}

void FatalError(const char* fmt, ...) {
  va_list args;
  va_start(args, fmt);
  LogLineVarargs('X', fmt, args);
  va_end(args);

#if XE_PLATFORM_WIN32
  if (!xe::has_console_attached()) {
    va_start(args, fmt);
    vsnprintf(log_format_buffer_.data(), log_format_buffer_.capacity(), fmt,
              args);
    va_end(args);
    MessageBoxA(NULL, log_format_buffer_.data(), "Xenia Error",
                MB_OK | MB_ICONERROR | MB_APPLMODAL | MB_SETFOREGROUND);
  }
#endif  // WIN32

  exit(1);
}

void FatalError(const std::string& str) { FatalError(str.c_str()); }

}  // namespace xe
<commit_msg>Fix empty line logging.<commit_after>/**
 ******************************************************************************
 * Xenia : Xbox 360 Emulator Research Project                                 *
 ******************************************************************************
 * Copyright 2013 Ben Vanik. All rights reserved.                             *
 * Released under the BSD license - see LICENSE in the root for more details. *
 ******************************************************************************
 */

#include "xenia/base/logging.h"

#include <gflags/gflags.h>

#include <atomic>
#include <cinttypes>
#include <cstdarg>
#include <mutex>
#include <vector>

#include "xenia/base/filesystem.h"
#include "xenia/base/main.h"
#include "xenia/base/math.h"
#include "xenia/base/ring_buffer.h"
#include "xenia/base/threading.h"

// For MessageBox:
// TODO(benvanik): generic API? logging_win.cc?
#if XE_PLATFORM_WIN32
#include "xenia/base/platform_win.h"
#endif  // XE_PLATFORM_WIN32

DEFINE_string(log_file, "",
              "Logs are written to the given file instead of the default.");
DEFINE_bool(flush_log, true, "Flush log file after each log line batch.");

namespace xe {

class Logger;

Logger* logger_ = nullptr;
thread_local std::vector<char> log_format_buffer_(64 * 1024);

class Logger {
 public:
  Logger(const std::wstring& app_name)
      : ring_buffer_(buffer_, kBufferSize), running_(true) {
    if (!FLAGS_log_file.empty()) {
      auto file_path = xe::to_wstring(FLAGS_log_file.c_str());
      xe::filesystem::CreateParentFolder(file_path);
      file_ = xe::filesystem::OpenFile(file_path, "wt");
    } else {
      auto file_path = app_name + L".log";
      file_ = xe::filesystem::OpenFile(file_path, "wt");
    }

    flush_event_ = xe::threading::Event::CreateAutoResetEvent(false);
    write_thread_ =
        xe::threading::Thread::Create({}, [this]() { WriteThread(); });
    write_thread_->set_name("xe::FileLogSink Writer");
  }

  ~Logger() {
    running_ = false;
    flush_event_->Set();
    xe::threading::Wait(write_thread_.get(), true);
    fflush(file_);
    fclose(file_);
  }

  void AppendLine(uint32_t thread_id, const char level_char, const char* buffer,
                  size_t buffer_length) {
    LogLine line;
    line.thread_id = thread_id;
    line.level_char = level_char;
    line.buffer_length = buffer_length;
    while (true) {
      mutex_.lock();
      if (ring_buffer_.write_count() < sizeof(line) + buffer_length) {
        // Buffer is full. Stall.
        mutex_.unlock();
        xe::threading::MaybeYield();
        continue;
      }
      ring_buffer_.Write(&line, sizeof(LogLine));
      ring_buffer_.Write(buffer, buffer_length);
      mutex_.unlock();
      break;
    }
    flush_event_->Set();
  }

 private:
  static const size_t kBufferSize = 32 * 1024 * 1024;

  struct LogLine {
    uint32_t thread_id;
    char level_char;
    size_t buffer_length;
  };

  void WriteThread() {
    while (running_) {
      mutex_.lock();
      bool did_write = false;
      while (!ring_buffer_.empty()) {
        did_write = true;

        // Read line header and write out the line prefix.
        LogLine line;
        ring_buffer_.Read(&line, sizeof(line));
        char prefix[] = {
            line.level_char,
            '>',
            ' ',
            '0',  // Thread ID gets placed here (8 chars).
            '0',
            '0',
            '0',
            '0',
            '0',
            '0',
            '0',
            ' ',
            0,
        };
        std::snprintf(prefix + 3, sizeof(prefix) - 3, "%08" PRIX32 " ",
                      line.thread_id);
        fwrite(prefix, 1, sizeof(prefix) - 1, file_);
        if (line.buffer_length) {
          // Get access to the line data - which may be split in the ring buffer
          // - and write it out in parts.
          auto line_range = ring_buffer_.BeginRead(line.buffer_length);
          fwrite(line_range.first, 1, line_range.first_length, file_);
          if (line_range.second_length) {
            fwrite(line_range.second, 1, line_range.second_length, file_);
          }
          // Always ensure there is a newline.
          char last_char = line_range.second
                               ? line_range.second[line_range.second_length - 1]
                               : line_range.first[line_range.first_length - 1];
          if (last_char != '\n') {
            const char suffix[1] = {'\n'};
            fwrite(suffix, 1, sizeof(suffix), file_);
          }
          ring_buffer_.EndRead(std::move(line_range));
        } else {
          const char suffix[1] = {'\n'};
          fwrite(suffix, 1, sizeof(suffix), file_);
        }
      }
      mutex_.unlock();
      if (did_write) {
        if (FLAGS_flush_log) {
          fflush(file_);
        }
      }
      xe::threading::Wait(flush_event_.get(), true);
    }
  }

  FILE* file_ = nullptr;
  uint8_t buffer_[kBufferSize];
  RingBuffer ring_buffer_;
  std::mutex mutex_;
  std::atomic<bool> running_;
  std::unique_ptr<xe::threading::Event> flush_event_;
  std::unique_ptr<xe::threading::Thread> write_thread_;
};

void InitializeLogging(const std::wstring& app_name) {
  // We leak this intentionally - lots of cleanup code needs it.
  logger_ = new Logger(app_name);
}

void LogLineFormat(const char level_char, const char* fmt, ...) {
  va_list args;
  va_start(args, fmt);
  size_t chars_written = vsnprintf(log_format_buffer_.data(),
                                   log_format_buffer_.capacity(), fmt, args);
  va_end(args);
  if (chars_written != std::string::npos) {
    logger_->AppendLine(xe::threading::current_thread_id(), level_char,
                        log_format_buffer_.data(), chars_written);
  } else {
    logger_->AppendLine(xe::threading::current_thread_id(), level_char, fmt,
                        std::strlen(fmt));
  }
}

void LogLineVarargs(const char level_char, const char* fmt, va_list args) {
  size_t chars_written = vsnprintf(log_format_buffer_.data(),
                                   log_format_buffer_.capacity(), fmt, args);
  logger_->AppendLine(xe::threading::current_thread_id(), level_char,
                      log_format_buffer_.data(), chars_written);
}

void LogLine(const char level_char, const char* str, size_t str_length) {
  logger_->AppendLine(
      xe::threading::current_thread_id(), level_char, str,
      str_length == std::string::npos ? std::strlen(str) : str_length);
}

void LogLine(const char level_char, const std::string& str) {
  logger_->AppendLine(xe::threading::current_thread_id(), level_char,
                      str.c_str(), str.length());
}

void FatalError(const char* fmt, ...) {
  va_list args;
  va_start(args, fmt);
  LogLineVarargs('X', fmt, args);
  va_end(args);

#if XE_PLATFORM_WIN32
  if (!xe::has_console_attached()) {
    va_start(args, fmt);
    vsnprintf(log_format_buffer_.data(), log_format_buffer_.capacity(), fmt,
              args);
    va_end(args);
    MessageBoxA(NULL, log_format_buffer_.data(), "Xenia Error",
                MB_OK | MB_ICONERROR | MB_APPLMODAL | MB_SETFOREGROUND);
  }
#endif  // WIN32

  exit(1);
}

void FatalError(const std::string& str) { FatalError(str.c_str()); }

}  // namespace xe
<|endoftext|>


<commit_before><commit_msg>don't write milliseconds when they are zero<commit_after><|endoftext|>


<commit_before>//  Copyright 2011 Gregory Szorc
//
//  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.

#ifndef ZIPPYLOG_HPP_
#define ZIPPYLOG_HPP_

// windows requires a special macro to export symbols from libraries
// we use the token ZIPPYLOG_IMPORT for this
// if we are on Windows, we export symbols by default.
// If ZIPPYLOG_IMPORT is defined, we tell the compiler we're looking for
// external symbols.
// Else, we're not on Windows and the keyword does nothing.
// @todo utilize GCC's visibility attribute (http://gcc.gnu.org/wiki/Visibility)
#ifdef WINDOWS
#if defined(ZIPPYLOG_IMPORT)
#define ZIPPYLOG_EXPORT __declspec(dllimport)
#else
#define ZIPPYLOG_EXPORT __declspec(dllexport)
#endif
#else
#define ZIPPYLOG_EXPORT
#endif

/* define 32 and 64 bit integer types */
// @todo these should be namespaced
#ifdef WINDOWS
typedef __int32 int32;
typedef __int64 int64;
typedef unsigned __int32 uint32;
typedef unsigned __int64 uint64;
#elif LINUX
#include <stdint.h>
typedef int32_t int32;
typedef int64_t int64;
typedef uint32_t uint32;
typedef uint64_t uint64;
#endif

#include <stdexcept>
#include <string>

namespace zippylog {

/// The base zippylog exception
///
/// Zippylog code is expected to throw an exception derived from this for all
/// run-time errors. Zippylog code is allowed to throw exceptions derived from
/// std::logic_error if it makes sense (e.g. obvious coding error)
class Exception : public ::std::runtime_error
{
    public:
        Exception(const ::std::string &msg) : ::std::runtime_error(msg) { }
};

/// An error when deserializing a message
class DeserializeException : public ::std::runtime_error
{
    public:
        DeserializeException() : runtime_error("could not deserialize message") { }
};

// initializes the zippylog system
// this should be called at the beginning of every program/library that uses zippylog
ZIPPYLOG_EXPORT void initialize_library();

// runs zippylog shutdown procedures
// This should be executed before process exit or when zippylog is no longer
// needed by a process.
//
// It isn't required to call this function. However, not doing so will result
// in leaked memory.
ZIPPYLOG_EXPORT void shutdown_library();

static const uint32 message_namespace = 1;

/// Default number of persisted state reactor threads for the server device
static const uint32 server_default_persisted_state_reactor_threads = 1;

/// Default number of worker threads for the server device
static const uint32 server_default_worker_threads = 2;

/// Default subscription TTL for server device (in milliseconds)
static const uint32 server_default_subscription_ttl = 60000;

/// Default stream flush interval for server device (in milliseconds)
static const uint32 server_default_stream_flush_interval = 5000;

/// Default bucket to log internal events to in server device
static const ::std::string server_default_log_bucket = "zippylog";

/// Default stream set to log internal events to in server device
static const ::std::string server_default_log_stream_set = "server";

/// Default value for whether to allow remote-supplied Lua code in server device
static const uint32 server_default_lua_allow = false;

/// Default maximum Lua allocation limit for streaming states, in bytes
static const uint32 server_default_lua_streaming_max_memory = 524288;

static const uint32 lua_default_subscription_memory_ceiling = 524288;

static const uint32 lua_default_plugin_memory_ceiling = 524288;

} // namespace

#endif<commit_msg>export exception classes from DLL<commit_after>//  Copyright 2011 Gregory Szorc
//
//  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.

#ifndef ZIPPYLOG_HPP_
#define ZIPPYLOG_HPP_

// windows requires a special macro to export symbols from libraries
// we use the token ZIPPYLOG_IMPORT for this
// if we are on Windows, we export symbols by default.
// If ZIPPYLOG_IMPORT is defined, we tell the compiler we're looking for
// external symbols.
// Else, we're not on Windows and the keyword does nothing.
// @todo utilize GCC's visibility attribute (http://gcc.gnu.org/wiki/Visibility)
#ifdef WINDOWS
#if defined(ZIPPYLOG_IMPORT)
#define ZIPPYLOG_EXPORT __declspec(dllimport)
#else
#define ZIPPYLOG_EXPORT __declspec(dllexport)
#endif
#else
#define ZIPPYLOG_EXPORT
#endif

/* define 32 and 64 bit integer types */
// @todo these should be namespaced
#ifdef WINDOWS
typedef __int32 int32;
typedef __int64 int64;
typedef unsigned __int32 uint32;
typedef unsigned __int64 uint64;
#elif LINUX
#include <stdint.h>
typedef int32_t int32;
typedef int64_t int64;
typedef uint32_t uint32;
typedef uint64_t uint64;
#endif

#include <stdexcept>
#include <string>

namespace zippylog {

/// The base zippylog exception
///
/// Zippylog code is expected to throw an exception derived from this for all
/// run-time errors. Zippylog code is allowed to throw exceptions derived from
/// std::logic_error if it makes sense (e.g. obvious coding error)
class ZIPPYLOG_EXPORT Exception : public ::std::runtime_error
{
    public:
        Exception(const ::std::string &msg) : ::std::runtime_error(msg) { }
};

/// An error when deserializing a message
class ZIPPYLOG_EXPORT DeserializeException : public ::std::runtime_error
{
    public:
        DeserializeException() : runtime_error("could not deserialize message") { }
};

// initializes the zippylog system
// this should be called at the beginning of every program/library that uses zippylog
ZIPPYLOG_EXPORT void initialize_library();

// runs zippylog shutdown procedures
// This should be executed before process exit or when zippylog is no longer
// needed by a process.
//
// It isn't required to call this function. However, not doing so will result
// in leaked memory.
ZIPPYLOG_EXPORT void shutdown_library();

static const uint32 message_namespace = 1;

/// Default number of persisted state reactor threads for the server device
static const uint32 server_default_persisted_state_reactor_threads = 1;

/// Default number of worker threads for the server device
static const uint32 server_default_worker_threads = 2;

/// Default subscription TTL for server device (in milliseconds)
static const uint32 server_default_subscription_ttl = 60000;

/// Default stream flush interval for server device (in milliseconds)
static const uint32 server_default_stream_flush_interval = 5000;

/// Default bucket to log internal events to in server device
static const ::std::string server_default_log_bucket = "zippylog";

/// Default stream set to log internal events to in server device
static const ::std::string server_default_log_stream_set = "server";

/// Default value for whether to allow remote-supplied Lua code in server device
static const uint32 server_default_lua_allow = false;

/// Default maximum Lua allocation limit for streaming states, in bytes
static const uint32 server_default_lua_streaming_max_memory = 524288;

static const uint32 lua_default_subscription_memory_ceiling = 524288;

static const uint32 lua_default_plugin_memory_ceiling = 524288;

} // namespace

#endif<|endoftext|>


<commit_before>void main()
{

}
<commit_msg>added hello world printf<commit_after>#include <stdio.h>

void main ()
{
	printf("hello world");
}
<|endoftext|>


<commit_before><commit_msg>More coding...<commit_after><|endoftext|>


<commit_before><commit_msg>Include paths, error checking, diagagnostics pretty printing etc<commit_after><|endoftext|>


<commit_before><commit_msg>Implement constant propagation for offsets<commit_after><|endoftext|>


<commit_before><commit_msg>xwayland: fix handling of output changes<commit_after><|endoftext|>


<commit_before><commit_msg>Don't traverse surfaces more than once<commit_after><|endoftext|>


<commit_before><commit_msg>wallet tx<commit_after><|endoftext|>


<commit_before><commit_msg>Do not pause before exit<commit_after><|endoftext|>


<commit_before>// //////////////////////////////////////////////////////////////////////
// Import section
// //////////////////////////////////////////////////////////////////////
// STL
#include <cassert>
#include <sstream>
// Boost.Serialization
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/access.hpp>
// StdAir
#include <stdair/basic/BasConst_Inventory.hpp>
#include <stdair/bom/FareFamily.hpp>

namespace stdair {

  // ////////////////////////////////////////////////////////////////////
  FareFamily::FareFamily() : _key (DEFAULT_FARE_FAMILY_CODE), _parent (NULL) {
    assert (false);
  }

  // ////////////////////////////////////////////////////////////////////
  FareFamily::FareFamily (const FareFamily& iFareFamily)
    : _key (iFareFamily._key),
      _parent (NULL),
      _meanStdDev (iFareFamily._meanStdDev) {
  }

  // ////////////////////////////////////////////////////////////////////
  FareFamily::FareFamily (const Key_T& iKey) : _key (iKey), _parent (NULL) {
  }

  // ////////////////////////////////////////////////////////////////////
  FareFamily::~FareFamily() {
  }

  // ////////////////////////////////////////////////////////////////////
  std::string FareFamily::toString() const {
    std::ostringstream oStr;
    oStr << describeKey();
    return oStr.str();
  }

  // ////////////////////////////////////////////////////////////////////
  void FareFamily::serialisationImplementationExport() const {
    std::ostringstream oStr;
    boost::archive::text_oarchive oa (oStr);
    oa << *this;
  }

  // ////////////////////////////////////////////////////////////////////
  void FareFamily::serialisationImplementationImport() {
    std::istringstream iStr;
    boost::archive::text_iarchive ia (iStr);
    ia >> *this;
  }

  // ////////////////////////////////////////////////////////////////////
  template<class Archive>
  void FareFamily::serialize (Archive& ioArchive,
                              const unsigned int iFileVersion) {
    ioArchive & _key;
  }

}

<commit_msg>[DEV] Added the disutility and the FRAT5 curves to the copy constructor of fare family.<commit_after>// //////////////////////////////////////////////////////////////////////
// Import section
// //////////////////////////////////////////////////////////////////////
// STL
#include <cassert>
#include <sstream>
// Boost.Serialization
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/access.hpp>
// StdAir
#include <stdair/basic/BasConst_Inventory.hpp>
#include <stdair/bom/FareFamily.hpp>

namespace stdair {

  // ////////////////////////////////////////////////////////////////////
  FareFamily::FareFamily() : _key (DEFAULT_FARE_FAMILY_CODE), _parent (NULL) {
    assert (false);
  }

  // ////////////////////////////////////////////////////////////////////
  FareFamily::FareFamily (const FareFamily& iFareFamily)
    : _key (iFareFamily._key),
      _parent (NULL),
      _frat5Curve (iFareFamily._frat5Curve),
      _disutilityCurve (iFareFamily._disutilityCurve),
      _meanStdDev (iFareFamily._meanStdDev) {
  }

  // ////////////////////////////////////////////////////////////////////
  FareFamily::FareFamily (const Key_T& iKey) : _key (iKey), _parent (NULL) {
  }

  // ////////////////////////////////////////////////////////////////////
  FareFamily::~FareFamily() {
  }

  // ////////////////////////////////////////////////////////////////////
  std::string FareFamily::toString() const {
    std::ostringstream oStr;
    oStr << describeKey();
    return oStr.str();
  }

  // ////////////////////////////////////////////////////////////////////
  void FareFamily::serialisationImplementationExport() const {
    std::ostringstream oStr;
    boost::archive::text_oarchive oa (oStr);
    oa << *this;
  }

  // ////////////////////////////////////////////////////////////////////
  void FareFamily::serialisationImplementationImport() {
    std::istringstream iStr;
    boost::archive::text_iarchive ia (iStr);
    ia >> *this;
  }

  // ////////////////////////////////////////////////////////////////////
  template<class Archive>
  void FareFamily::serialize (Archive& ioArchive,
                              const unsigned int iFileVersion) {
    ioArchive & _key;
  }

}

<|endoftext|>


<commit_before>//----------------------------  multithread_info.cc  ----------------
//    $Id$
//    Version: $Name$
//
//    Copyright (C) 1998, 1999, 2000, 2001, 2002 by the deal authors
//
//    This file is subject to QPL and may not be  distributed
//    without copyright and license information. Please refer
//    to the file deal.II/doc/license.html for the  text  and
//    further information on this license.
//
//----------------------------  multithread_info.cc  ----------------

#include <base/multithread_info.h>

#if defined(__linux__)
#  include <fstream>
#  include <string>
#endif

#if defined(__sun__)
#  include <unistd.h>
#endif

#ifdef DEAL_II_USE_MT

#if defined(__linux__)

unsigned int MultithreadInfo::get_n_cpus()
{
  std::ifstream cpuinfo;
  std::string search;
  unsigned int nCPU = 0;

  cpuinfo.open("/proc/cpuinfo");

  AssertThrow(cpuinfo,ExcProcNotPresent());

  while(cpuinfo)
    {
      cpuinfo >> search;
      if (search.find("processor")!=std::string::npos)
	nCPU++;
    }
  cpuinfo.close();

  return nCPU;
}

#elif defined(__sun__) || defined(__osf__)

unsigned int MultithreadInfo::get_n_cpus()
{
  return sysconf(_SC_NPROCESSORS_ONLN);
}

#else

// if you get to see this warning, then this can have two reasons: either
// because you fell through all of the above #if clauses and on your system
// the detection of processors is really not implemented, or you are using
// a compiler that does not understand the #warning directive, in which case
// you will see a report on the screen even if the detection of processors
// is implemented for your system. In the latter case, you need not worry
// about the warning (although it is acknowledged that it is annoying),
// otherwise you might want to consider implementing the missing feature
// and submitting it back to the authors of the library.
#warning Detection of Processors not supported on this OS

unsigned int MultithreadInfo::get_n_cpus()
{
  return 1;
}

#endif

#else				 // not in multithreadmode

unsigned int MultithreadInfo::get_n_cpus()
{
  return 1;
}

#endif

MultithreadInfo::MultithreadInfo () :
                n_cpus (get_n_cpus()),
                n_default_threads (n_cpus)
{};

unsigned int
MultithreadInfo::memory_consumption ()
{
				   // only simple data elements, so
				   // use sizeof operator
  return sizeof (MultithreadInfo);
};

// definition of the variable which is declared `extern' in the .h file
MultithreadInfo multithread_info;
<commit_msg>Added sysconf(_SC_NPROC_ONLN) call for SGI to determine the number of available processors when in multithread mode<commit_after>//----------------------------  multithread_info.cc  ----------------
//    $Id$
//    Version: $Name$
//
//    Copyright (C) 1998, 1999, 2000, 2001, 2002 by the deal authors
//
//    This file is subject to QPL and may not be  distributed
//    without copyright and license information. Please refer
//    to the file deal.II/doc/license.html for the  text  and
//    further information on this license.
//
//----------------------------  multithread_info.cc  ----------------

#include <base/multithread_info.h>

#if defined(__linux__)
#  include <fstream>
#  include <string>
#endif

#if defined(__sun__)
#  include <unistd.h>
#endif

#if defined(__sgi__)
#  include <unistd.h>
#endif

#ifdef DEAL_II_USE_MT

#if defined(__linux__)

unsigned int MultithreadInfo::get_n_cpus()
{
  std::ifstream cpuinfo;
  std::string search;
  unsigned int nCPU = 0;

  cpuinfo.open("/proc/cpuinfo");

  AssertThrow(cpuinfo,ExcProcNotPresent());

  while(cpuinfo)
    {
      cpuinfo >> search;
      if (search.find("processor")!=std::string::npos)
	nCPU++;
    }
  cpuinfo.close();

  return nCPU;
}

#elif defined(__sun__) || defined(__osf__)

unsigned int MultithreadInfo::get_n_cpus()
{
  return sysconf(_SC_NPROCESSORS_ONLN);
}

#elif defined(__sgi__)

unsigned int MultithreadInfo::get_n_cpus()
{
  return sysconf(_SC_NPROC_ONLN);
}

#else

// if you get to see this warning, then this can have two reasons: either
// because you fell through all of the above #if clauses and on your system
// the detection of processors is really not implemented, or you are using
// a compiler that does not understand the #warning directive, in which case
// you will see a report on the screen even if the detection of processors
// is implemented for your system. In the latter case, you need not worry
// about the warning (although it is acknowledged that it is annoying),
// otherwise you might want to consider implementing the missing feature
// and submitting it back to the authors of the library.
#warning Detection of Processors not supported on this OS

unsigned int MultithreadInfo::get_n_cpus()
{
  return 1;
}

#endif

#else				 // not in multithreadmode

unsigned int MultithreadInfo::get_n_cpus()
{
  return 1;
}

#endif

MultithreadInfo::MultithreadInfo () :
                n_cpus (get_n_cpus()),
                n_default_threads (n_cpus)
{};

unsigned int
MultithreadInfo::memory_consumption ()
{
				   // only simple data elements, so
				   // use sizeof operator
  return sizeof (MultithreadInfo);
};

// definition of the variable which is declared `extern' in the .h file
MultithreadInfo multithread_info;
<|endoftext|>


<commit_before>/*
    This file is part of KXForms.

    Copyright (c) 2005,2006 Cornelius Schumacher <schumacher@kde.org>

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

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

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.
*/

#include "guihandler.h"

#include "manager.h"

#include <kdebug.h>
#include <kmessagebox.h>
#include <klocale.h>

#include <QLabel>
#include <QVBoxLayout>
#include <QFrame>

using namespace KXForms;

GuiHandler::GuiHandler( Manager *m )
  : mManager( m ), mLayoutStyle( Grid )
{
  mManager->setGuiHandler( this );
}

GuiHandler::~GuiHandler()
{
}

Manager *GuiHandler::manager() const
{
  return mManager;
}

QLayout *GuiHandler::getTopLayout() const
{
  if( layoutStyle() == GuiHandler::Grid ) {
    QGridLayout *l = new QGridLayout();
    return l;
  }
  else {
    QVBoxLayout *l = new QVBoxLayout();
    l->addStretch( 1 );
    return l;
  }
}

void GuiHandler::addWidget( QLayout *l, QWidget *w ) const
{
  if( layoutStyle() == GuiHandler::Grid ) {
    QGridLayout *gl = dynamic_cast< QGridLayout *>( l );
    if( !gl )
      return;

    gl->addWidget( w, gl->rowCount(), 0, 1, 3 );
  }
  else {
    QVBoxLayout *vbl = dynamic_cast< QVBoxLayout *>( l );
    if( !vbl )
      return;

    vbl->insertWidget( l->count() - 1, w );
  }
}

void GuiHandler::addElement( QLayout *l, QWidget *label, QWidget *widget,
            GuiElement::Properties *prop, bool indented ) const
{
  Q_UNUSED( prop );
  if( layoutStyle() == GuiHandler::Grid ) {
    QGridLayout *gl = dynamic_cast< QGridLayout *>( l );
    if( !gl )
      return;

    int row = gl->rowCount();
    gl->setColumnStretch( 2, 1 );
    if( label ) {
      if( indented ) {
        gl->addWidget( label, row, 0, 1, 2, Qt::AlignRight | Qt::AlignTop );
        gl->addWidget( widget, row, 2 );
      }
      else {
        gl->addWidget( label, row, 0, Qt::AlignRight | Qt::AlignTop );
        gl->addWidget( widget, row, 1, 1, 2 );
      }
    }
    else {
      gl->addWidget( widget, row, 0, 1, 3 );
    }
  }
  else {
    QVBoxLayout *vbl = dynamic_cast< QVBoxLayout *>( l );
    if( !vbl )
      return;

    QBoxLayout *newLayout;
    newLayout = new QVBoxLayout();

    if( indented ) {
      QBoxLayout *labelLayout = new QHBoxLayout();
      labelLayout->addSpacing( 40 );
      labelLayout->addWidget( label, Qt::AlignRight | Qt::AlignTop );
      QBoxLayout *widgetLayout = new QHBoxLayout();
      widgetLayout->addSpacing( 40 );
      widgetLayout->addWidget( widget, Qt::AlignRight | Qt::AlignTop );
      newLayout->addLayout( labelLayout );
      newLayout->addLayout( widgetLayout );
    } else {
      newLayout->addWidget( label, Qt::AlignRight | Qt::AlignTop );
      newLayout->addWidget( widget );
    }

    vbl->insertLayout( l->count() - 1, newLayout );
  }
}

void GuiHandler::addElement( QLayout *l, QWidget *label, QWidget *widget, int x, int y, int width, int height,
            GuiElement::Properties *prop, bool indented ) const
{
  Q_UNUSED( prop );
  Q_UNUSED( indented );
  //TODO: fix vertical layout-style
  //TODO: make indention work again
  if( layoutStyle() == GuiHandler::Grid ) {
    QGridLayout *gl = dynamic_cast< QGridLayout *>( l );
    if( !gl )
      return;

    gl->setColumnStretch( (2*x)+1, 1 );
    if( label ) {
      qDebug() << "Adding label at: (" << y << "," << 2*x << ")";
      gl->addWidget( label, y, (2*x), height, 1, Qt::AlignRight | Qt::AlignTop );
      qDebug() << "Adding widget at: (" << y << "," << (2*x)+1 << ") (" << height << "," << (2*width)-1  << ")";
      gl->addWidget( widget, y, (2*x)+1, height, (2*width)-1 );
    }
    else {
      gl->addWidget( widget, y, (2*x), height, 2*width );
    }
  }
}
<commit_msg>Make indention work again<commit_after>/*
    This file is part of KXForms.

    Copyright (c) 2005,2006 Cornelius Schumacher <schumacher@kde.org>

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

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

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.
*/

#include "guihandler.h"

#include "manager.h"

#include <kdebug.h>
#include <kmessagebox.h>
#include <klocale.h>

#include <QLabel>
#include <QVBoxLayout>
#include <QFrame>

using namespace KXForms;

GuiHandler::GuiHandler( Manager *m )
  : mManager( m ), mLayoutStyle( Grid )
{
  mManager->setGuiHandler( this );
}

GuiHandler::~GuiHandler()
{
}

Manager *GuiHandler::manager() const
{
  return mManager;
}

QLayout *GuiHandler::getTopLayout() const
{
  if( layoutStyle() == GuiHandler::Grid ) {
    QGridLayout *l = new QGridLayout();
    return l;
  }
  else {
    QVBoxLayout *l = new QVBoxLayout();
    l->addStretch( 1 );
    return l;
  }
}

void GuiHandler::addWidget( QLayout *l, QWidget *w ) const
{
  if( layoutStyle() == GuiHandler::Grid ) {
    QGridLayout *gl = dynamic_cast< QGridLayout *>( l );
    if( !gl )
      return;

    gl->addWidget( w, gl->rowCount(), 0, 1, 3 );
  }
  else {
    QVBoxLayout *vbl = dynamic_cast< QVBoxLayout *>( l );
    if( !vbl )
      return;

    vbl->insertWidget( l->count() - 1, w );
  }
}

void GuiHandler::addElement( QLayout *l, QWidget *label, QWidget *widget,
            GuiElement::Properties *prop, bool indented ) const
{
  Q_UNUSED( prop );
  if( layoutStyle() == GuiHandler::Grid ) {
    QGridLayout *gl = dynamic_cast< QGridLayout *>( l );
    if( !gl )
      return;

    int row = gl->rowCount();
    gl->setColumnStretch( 2, 1 );
    if( label ) {
      if( indented ) {
        gl->addWidget( label, row, 0, 1, 2, Qt::AlignRight | Qt::AlignTop );
        gl->addWidget( widget, row, 2 );
      }
      else {
        gl->addWidget( label, row, 0, Qt::AlignRight | Qt::AlignTop );
        gl->addWidget( widget, row, 1, 1, 2 );
      }
    }
    else {
      gl->addWidget( widget, row, 0, 1, 3 );
    }
  }
  else {
    QVBoxLayout *vbl = dynamic_cast< QVBoxLayout *>( l );
    if( !vbl )
      return;

    QBoxLayout *newLayout;
    newLayout = new QVBoxLayout();

    if( indented ) {
      QBoxLayout *labelLayout = new QHBoxLayout();
      labelLayout->addSpacing( 40 );
      labelLayout->addWidget( label, Qt::AlignRight | Qt::AlignTop );
      QBoxLayout *widgetLayout = new QHBoxLayout();
      widgetLayout->addSpacing( 40 );
      widgetLayout->addWidget( widget, Qt::AlignRight | Qt::AlignTop );
      newLayout->addLayout( labelLayout );
      newLayout->addLayout( widgetLayout );
    } else {
      newLayout->addWidget( label, Qt::AlignRight | Qt::AlignTop );
      newLayout->addWidget( widget );
    }

    vbl->insertLayout( l->count() - 1, newLayout );
  }
}

void GuiHandler::addElement( QLayout *l, QWidget *label, QWidget *widget, int x, int y, int width, int height,
            GuiElement::Properties *prop, bool indented ) const
{
  Q_UNUSED( prop );
  Q_UNUSED( indented );
  //TODO: fix vertical layout-style
  if( layoutStyle() == GuiHandler::Grid ) {
    QGridLayout *gl = dynamic_cast< QGridLayout *>( l );
    if( !gl )
      return;

    gl->setColumnStretch( (2*x)+1, 1 );
    if( label ) {
      qDebug() << "Adding label at: (" << y << "," << 2*x << ")";
      gl->addWidget( label, y, (2*x), height, 1, Qt::AlignRight | Qt::AlignTop );
      qDebug() << "Adding widget at: (" << y << "," << (2*x)+1 << ") (" << height << "," << (2*width)-1  << ")";
      if( indented ) {
        QHBoxLayout *hbl = new QHBoxLayout();
        hbl->addSpacing( 40 );
        hbl->addWidget( widget );
        gl->addLayout( hbl, y, (2*x)+1, height, (2*width)-1 );
      }
      else
        gl->addWidget( widget, y, (2*x)+1, height, (2*width)-1 );
    }
    else {
      if( indented ) {
        QHBoxLayout *hbl = new QHBoxLayout();
        hbl->addSpacing( 40 );
        hbl->addWidget( widget );
        gl->addLayout( hbl, y, (2*x), height, 2*width );
      }
        gl->addWidget( widget, y, (2*x), height, 2*width );
    }
  }
}
<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////////
/// @brief Aql, query context
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2014 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// 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.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Jan Steemann
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
/// @author Copyright 2012-2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////

#include "Aql/Query.h"
#include "Aql/ExecutionBlock.h"
#include "Aql/ExecutionPlan.h"
#include "Aql/Parser.h"
#include "Aql/V8Executor.h"
#include "BasicsC/json.h"
#include "BasicsC/tri-strings.h"
#include "Utils/Exception.h"
#include "VocBase/vocbase.h"

using namespace triagens::aql;

// -----------------------------------------------------------------------------
// --SECTION--                                        constructors / destructors
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief creates a query
////////////////////////////////////////////////////////////////////////////////

Query::Query (TRI_vocbase_t* vocbase,
              char const* queryString,
              size_t queryLength,
              TRI_json_t* bindParameters)
  : _vocbase(vocbase),
    _executor(nullptr),
    _queryString(queryString),
    _queryLength(queryLength),
    _type(AQL_QUERY_READ),
    _bindParameters(bindParameters),
    _strings() {

  TRI_ASSERT(_vocbase != nullptr);

  _strings.reserve(32);
}

////////////////////////////////////////////////////////////////////////////////
/// @brief destroys a query
////////////////////////////////////////////////////////////////////////////////

Query::~Query () {
  if (_executor != nullptr) {
    delete _executor;
    _executor = nullptr;
  }

  // free strings
  for (auto it = _strings.begin(); it != _strings.end(); ++it) {
    TRI_FreeString(TRI_UNKNOWN_MEM_ZONE, const_cast<char*>(*it));
  }
}

// -----------------------------------------------------------------------------
// --SECTION--                                                    public methods
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief extract a region from the query
////////////////////////////////////////////////////////////////////////////////

std::string Query::extractRegion (int line,
                                  int column) const {
  // note: line numbers reported by bison/flex start at 1, columns start at 0
  int currentLine   = 1;
  int currentColumn = 0;

  char c;
  char const* p = _queryString;

  while ((c = *p)) {
    if (currentLine > line ||
        (currentLine >= line && currentColumn >= column)) {
      break;
    }

    if (c == '\n') {
      ++p;
      ++currentLine;
      currentColumn = 0;
    }
    else if (c == '\r') {
      ++p;
      ++currentLine;
      currentColumn = 0;

      // eat a following newline
      if (*p == '\n') {
        ++p;
      }
    }
    else {
      ++currentColumn;
      ++p;
    }
  }

  // p is pointing at the position in the query the parse error occurred at
  TRI_ASSERT(p >= _queryString);

  size_t offset = static_cast<size_t>(p - _queryString);

  static int const   SNIPPET_LENGTH = 32;
  static char const* SNIPPET_SUFFIX = "...";

  if (_queryLength < offset + SNIPPET_LENGTH) {
    // return a copy of the region
    return std::string(_queryString + offset, _queryLength - offset);
  }

  // copy query part
  std::string result(_queryString + offset, SNIPPET_LENGTH);
  result.append(SNIPPET_SUFFIX);

  return result;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief register an error
////////////////////////////////////////////////////////////////////////////////

void Query::registerError (int code,
                           char const* details) {

  TRI_ASSERT(code != TRI_ERROR_NO_ERROR);

  if (details == nullptr) {
    THROW_ARANGO_EXCEPTION(code);
  }
  else {
    THROW_ARANGO_EXCEPTION_STRING(code, details);
  }
}

////////////////////////////////////////////////////////////////////////////////
/// @brief execute an AQL query - TODO: implement and determine return type
////////////////////////////////////////////////////////////////////////////////

QueryResult Query::execute () {
  try {
    Parser parser(this);
    parser.parse();
    parser.ast()->injectBindParameters(_bindParameters);
    parser.ast()->optimize();

    auto plan = ExecutionPlan::instanciateFromAst(parser.ast());

    try {
      auto exec = ExecutionBlock::instanciatePlan(plan);

      try {
        exec->staticAnalysis();

        exec->initialize();
        exec->execute();

        AqlItemBlock* value;
        while (nullptr != (value = exec->getOne())) {
          std::cout << value->getValue(0, 0)->toString() << std::endl;
          delete value;
        }

        exec->shutdown();
        delete exec;
      }
      catch (...) {
        delete exec;
        delete plan;
        // TODO: convert exception code
        return QueryResult(TRI_ERROR_INTERNAL);
      }
    }
    catch (triagens::arango::Exception const& ex) {
      delete plan;
      return QueryResult(ex.code(), ex.message());
    }
    catch (...) {
      delete plan;
      // TODO: convert exception code
      return QueryResult(TRI_ERROR_INTERNAL);
    }

    delete plan;

    QueryResult result(TRI_ERROR_NO_ERROR);
    // result.json = parser.ast()->toJson(TRI_UNKNOWN_MEM_ZONE);

    return result;
  }
  catch (triagens::arango::Exception const& ex) {
    return QueryResult(ex.code(), ex.message());
  }
  catch (...) {
    return QueryResult(TRI_ERROR_OUT_OF_MEMORY, TRI_errno_string(TRI_ERROR_OUT_OF_MEMORY));
  }
}

////////////////////////////////////////////////////////////////////////////////
/// @brief parse an AQL query
////////////////////////////////////////////////////////////////////////////////

QueryResult Query::parse () {
  try {
    Parser parser(this);
    return parser.parse();
  }
  catch (triagens::arango::Exception const& ex) {
    return QueryResult(ex.code(), ex.message());
  }
  catch (...) {
    return QueryResult(TRI_ERROR_OUT_OF_MEMORY, TRI_errno_string(TRI_ERROR_OUT_OF_MEMORY));
  }
}

////////////////////////////////////////////////////////////////////////////////
/// @brief explain an AQL query - TODO: implement and determine return type
////////////////////////////////////////////////////////////////////////////////

void Query::explain () {
}

////////////////////////////////////////////////////////////////////////////////
/// @brief get v8 executor
////////////////////////////////////////////////////////////////////////////////

V8Executor* Query::executor () {
  if (_executor == nullptr) {
    // the executor is a singleton per query
    _executor = new V8Executor;
  }

  TRI_ASSERT(_executor != nullptr);
  return _executor;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief register a string
/// the string is freed when the query is destroyed
////////////////////////////////////////////////////////////////////////////////

char* Query::registerString (char const* p,
                             size_t length,
                             bool mustUnescape) {

  if (p == nullptr) {
    THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
  }

  if (length == 0) {
    static char const* empty = "";
    // optimisation for the empty string
    return const_cast<char*>(empty);
  }

  char* copy = nullptr;
  if (mustUnescape) {
    size_t outLength;
    copy = TRI_UnescapeUtf8StringZ(TRI_UNKNOWN_MEM_ZONE, p, length, &outLength);
  }
  else {
    copy = TRI_DuplicateString2Z(TRI_UNKNOWN_MEM_ZONE, p, length);
  }

  if (copy == nullptr) {
    THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
  }

  try {
    _strings.push_back(copy);
  }
  catch (...) {
    THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
  }

  return copy;
}

// -----------------------------------------------------------------------------
// --SECTION--                                                       END-OF-FILE
// -----------------------------------------------------------------------------

// Local Variables:
// mode: outline-minor
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
// End:
<commit_msg>renaming<commit_after>////////////////////////////////////////////////////////////////////////////////
/// @brief Aql, query context
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2014 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// 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.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Jan Steemann
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
/// @author Copyright 2012-2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////

#include "Aql/Query.h"
#include "Aql/ExecutionBlock.h"
#include "Aql/ExecutionEngine.h"
#include "Aql/ExecutionPlan.h"
#include "Aql/Parser.h"
#include "Aql/V8Executor.h"
#include "BasicsC/json.h"
#include "BasicsC/tri-strings.h"
#include "Utils/Exception.h"
#include "VocBase/vocbase.h"

using namespace triagens::aql;

// -----------------------------------------------------------------------------
// --SECTION--                                        constructors / destructors
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief creates a query
////////////////////////////////////////////////////////////////////////////////

Query::Query (TRI_vocbase_t* vocbase,
              char const* queryString,
              size_t queryLength,
              TRI_json_t* bindParameters)
  : _vocbase(vocbase),
    _executor(nullptr),
    _queryString(queryString),
    _queryLength(queryLength),
    _type(AQL_QUERY_READ),
    _bindParameters(bindParameters),
    _strings() {

  TRI_ASSERT(_vocbase != nullptr);

  _strings.reserve(32);
}

////////////////////////////////////////////////////////////////////////////////
/// @brief destroys a query
////////////////////////////////////////////////////////////////////////////////

Query::~Query () {
  if (_executor != nullptr) {
    delete _executor;
    _executor = nullptr;
  }

  // free strings
  for (auto it = _strings.begin(); it != _strings.end(); ++it) {
    TRI_FreeString(TRI_UNKNOWN_MEM_ZONE, const_cast<char*>(*it));
  }
}

// -----------------------------------------------------------------------------
// --SECTION--                                                    public methods
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief extract a region from the query
////////////////////////////////////////////////////////////////////////////////

std::string Query::extractRegion (int line,
                                  int column) const {
  // note: line numbers reported by bison/flex start at 1, columns start at 0
  int currentLine   = 1;
  int currentColumn = 0;

  char c;
  char const* p = _queryString;

  while ((c = *p)) {
    if (currentLine > line ||
        (currentLine >= line && currentColumn >= column)) {
      break;
    }

    if (c == '\n') {
      ++p;
      ++currentLine;
      currentColumn = 0;
    }
    else if (c == '\r') {
      ++p;
      ++currentLine;
      currentColumn = 0;

      // eat a following newline
      if (*p == '\n') {
        ++p;
      }
    }
    else {
      ++currentColumn;
      ++p;
    }
  }

  // p is pointing at the position in the query the parse error occurred at
  TRI_ASSERT(p >= _queryString);

  size_t offset = static_cast<size_t>(p - _queryString);

  static int const   SNIPPET_LENGTH = 32;
  static char const* SNIPPET_SUFFIX = "...";

  if (_queryLength < offset + SNIPPET_LENGTH) {
    // return a copy of the region
    return std::string(_queryString + offset, _queryLength - offset);
  }

  // copy query part
  std::string result(_queryString + offset, SNIPPET_LENGTH);
  result.append(SNIPPET_SUFFIX);

  return result;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief register an error
////////////////////////////////////////////////////////////////////////////////

void Query::registerError (int code,
                           char const* details) {

  TRI_ASSERT(code != TRI_ERROR_NO_ERROR);

  if (details == nullptr) {
    THROW_ARANGO_EXCEPTION(code);
  }
  else {
    THROW_ARANGO_EXCEPTION_STRING(code, details);
  }
}

////////////////////////////////////////////////////////////////////////////////
/// @brief execute an AQL query - TODO: implement and determine return type
////////////////////////////////////////////////////////////////////////////////

QueryResult Query::execute () {
  try {
    Parser parser(this);
    parser.parse();
    parser.ast()->injectBindParameters(_bindParameters);
    parser.ast()->optimize();

    auto plan = ExecutionPlan::instanciateFromAst(parser.ast());

    try {
      auto engine = ExecutionEngine::instanciateFromPlan(plan->root());

      try {
        auto root = engine->root();
        root->execute();

        AqlItemBlock* value;
        while (nullptr != (value = root->getOne())) {
          std::cout << value->getValue(0, 0)->toString() << std::endl;
          delete value;
        }

        delete engine;
      }
      catch (...) {
        delete engine;
        delete plan;
        // TODO: convert exception code
        return QueryResult(TRI_ERROR_INTERNAL);
      }
    }
    catch (triagens::arango::Exception const& ex) {
      delete plan;
      return QueryResult(ex.code(), ex.message());
    }
    catch (...) {
      delete plan;
      // TODO: convert exception code
      return QueryResult(TRI_ERROR_INTERNAL);
    }

    delete plan;

    QueryResult result(TRI_ERROR_NO_ERROR);
    // result.json = parser.ast()->toJson(TRI_UNKNOWN_MEM_ZONE);

    return result;
  }
  catch (triagens::arango::Exception const& ex) {
    return QueryResult(ex.code(), ex.message());
  }
  catch (...) {
    return QueryResult(TRI_ERROR_OUT_OF_MEMORY, TRI_errno_string(TRI_ERROR_OUT_OF_MEMORY));
  }
}

////////////////////////////////////////////////////////////////////////////////
/// @brief parse an AQL query
////////////////////////////////////////////////////////////////////////////////

QueryResult Query::parse () {
  try {
    Parser parser(this);
    return parser.parse();
  }
  catch (triagens::arango::Exception const& ex) {
    return QueryResult(ex.code(), ex.message());
  }
  catch (...) {
    return QueryResult(TRI_ERROR_OUT_OF_MEMORY, TRI_errno_string(TRI_ERROR_OUT_OF_MEMORY));
  }
}

////////////////////////////////////////////////////////////////////////////////
/// @brief explain an AQL query - TODO: implement and determine return type
////////////////////////////////////////////////////////////////////////////////

void Query::explain () {
}

////////////////////////////////////////////////////////////////////////////////
/// @brief get v8 executor
////////////////////////////////////////////////////////////////////////////////

V8Executor* Query::executor () {
  if (_executor == nullptr) {
    // the executor is a singleton per query
    _executor = new V8Executor;
  }

  TRI_ASSERT(_executor != nullptr);
  return _executor;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief register a string
/// the string is freed when the query is destroyed
////////////////////////////////////////////////////////////////////////////////

char* Query::registerString (char const* p,
                             size_t length,
                             bool mustUnescape) {

  if (p == nullptr) {
    THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
  }

  if (length == 0) {
    static char const* empty = "";
    // optimisation for the empty string
    return const_cast<char*>(empty);
  }

  char* copy = nullptr;
  if (mustUnescape) {
    size_t outLength;
    copy = TRI_UnescapeUtf8StringZ(TRI_UNKNOWN_MEM_ZONE, p, length, &outLength);
  }
  else {
    copy = TRI_DuplicateString2Z(TRI_UNKNOWN_MEM_ZONE, p, length);
  }

  if (copy == nullptr) {
    THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
  }

  try {
    _strings.push_back(copy);
  }
  catch (...) {
    THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
  }

  return copy;
}

// -----------------------------------------------------------------------------
// --SECTION--                                                       END-OF-FILE
// -----------------------------------------------------------------------------

// Local Variables:
// mode: outline-minor
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
// End:
<|endoftext|>


<commit_before>#ifndef ARBITER_IS_AMALGAMATION
#include <arbiter/util/time.hpp>
#endif

#include <ctime>
#include <iomanip>
#include <iostream>
#include <mutex>
#include <sstream>

#ifndef ARBITER_IS_AMALGAMATION
#include <arbiter/util/types.hpp>
#endif

#ifdef ARBITER_CUSTOM_NAMESPACE
namespace ARBITER_CUSTOM_NAMESPACE
{
#endif

namespace arbiter
{

namespace
{
    std::mutex mutex;

    int64_t utcOffsetSeconds(const std::time_t& now)
    {
        std::lock_guard<std::mutex> lock(mutex);
        std::tm utc(*std::gmtime(&now));
        std::tm loc(*std::localtime(&now));
        return (int64_t)std::difftime(std::mktime(&utc), std::mktime(&loc));
    }
}

const std::string Time::iso8601 = "%Y-%m-%dT%H:%M:%SZ";
const std::string Time::iso8601NoSeparators = "%Y%m%dT%H%M%SZ";
const std::string Time::dateNoSeparators = "%Y%m%d";

Time::Time()
{
    m_time = std::time(nullptr);
}

Time::Time(const std::string& s, const std::string& format)
{
    std::tm tm{};

#ifndef ARBITER_WINDOWS
    // We'd prefer to use get_time, but it has poor compiler support.
    if (!strptime(s.c_str(), format.c_str(), &tm))
    {
        throw ArbiterError("Failed to parse " + s + " as time: " + format);
    }
#else
    std::istringstream ss(s);
    ss >> std::get_time(&tm, format.c_str());
    if (ss.fail())
    {
        throw ArbiterError("Failed to parse " + s + " as time: " + format);
    }
#endif
    const int64_t utcOffset(utcOffsetSeconds(std::mktime(&tm)));

    if (utcOffset > std::numeric_limits<int>::max())
        throw ArbiterError("Can't convert offset time in seconds to tm type.");
    tm.tm_sec -= (int)utcOffset;
    m_time = std::mktime(&tm);
}

std::string Time::str(const std::string& format) const
{
    std::lock_guard<std::mutex> lock(mutex);
#ifndef ARBITER_WINDOWS
    // We'd prefer to use put_time, but it has poor compiler support.
    // We're already locked here for gmtime, so might as well make this static.
    static std::vector<char> s(256, 0);

    const std::size_t size =
        strftime(s.data(), s.size(), format.c_str(), std::gmtime(&m_time));

    return std::string(s.data(), s.data() + size);
#else
    std::ostringstream ss;
    ss << std::put_time(std::gmtime(&m_time), format.c_str());
    return ss.str();
#endif
}

int64_t Time::operator-(const Time& other) const
{
    return (int64_t)std::difftime(m_time, other.m_time);
}

int64_t Time::asUnix() const
{
    static const Time epoch("1970-01-01T00:00:00Z");
    return *this - epoch;
}

} // namespace arbiter

#ifdef ARBITER_CUSTOM_NAMESPACE
}
#endif

<commit_msg>Updated to use std::time() if std::mktime() fails<commit_after>#ifndef ARBITER_IS_AMALGAMATION
#include <arbiter/util/time.hpp>
#endif

#include <ctime>
#include <iomanip>
#include <iostream>
#include <mutex>
#include <sstream>

#ifndef ARBITER_IS_AMALGAMATION
#include <arbiter/util/types.hpp>
#endif

#ifdef ARBITER_CUSTOM_NAMESPACE
namespace ARBITER_CUSTOM_NAMESPACE
{
#endif

namespace arbiter
{

namespace
{
    std::mutex mutex;

    int64_t utcOffsetSeconds(const std::time_t& now)
    {
        std::lock_guard<std::mutex> lock(mutex);
        std::tm utc(*std::gmtime(&now));
        std::tm loc(*std::localtime(&now));
        return (int64_t)std::difftime(std::mktime(&utc), std::mktime(&loc));
    }
}

const std::string Time::iso8601 = "%Y-%m-%dT%H:%M:%SZ";
const std::string Time::iso8601NoSeparators = "%Y%m%dT%H%M%SZ";
const std::string Time::dateNoSeparators = "%Y%m%d";

Time::Time()
{
    m_time = std::time(nullptr);
}

Time::Time(const std::string& s, const std::string& format)
{
    std::tm tm{};

#ifndef ARBITER_WINDOWS
    // We'd prefer to use get_time, but it has poor compiler support.
    if (!strptime(s.c_str(), format.c_str(), &tm))
    {
        throw ArbiterError("Failed to parse " + s + " as time: " + format);
    }
#else
    std::istringstream ss(s);
    ss >> std::get_time(&tm, format.c_str());
    if (ss.fail())
    {
        throw ArbiterError("Failed to parse " + s + " as time: " + format);
    }
#endif
    std::time_t time = std::mktime(&tm)!=-1 ? std::mktime(&tm) :std::time(nullptr);
    const int64_t utcOffset(utcOffsetSeconds(time));

    if (utcOffset > std::numeric_limits<int>::max())
        throw ArbiterError("Can't convert offset time in seconds to tm type.");
    tm.tm_sec -= (int)utcOffset;
    m_time = std::mktime(&tm);
}

std::string Time::str(const std::string& format) const
{
    std::lock_guard<std::mutex> lock(mutex);
#ifndef ARBITER_WINDOWS
    // We'd prefer to use put_time, but it has poor compiler support.
    // We're already locked here for gmtime, so might as well make this static.
    static std::vector<char> s(256, 0);

    const std::size_t size =
        strftime(s.data(), s.size(), format.c_str(), std::gmtime(&m_time));

    return std::string(s.data(), s.data() + size);
#else
    std::ostringstream ss;
    ss << std::put_time(std::gmtime(&m_time), format.c_str());
    return ss.str();
#endif
}

int64_t Time::operator-(const Time& other) const
{
    return (int64_t)std::difftime(m_time, other.m_time);
}

int64_t Time::asUnix() const
{
    static const Time epoch("1970-01-01T00:00:00Z");
    return *this - epoch;
}

} // namespace arbiter

#ifdef ARBITER_CUSTOM_NAMESPACE
}
#endif

<|endoftext|>