<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ash/wm/system_modal_container_layout_manager.h"

#include "ash/ash_switches.h"
#include "ash/shell.h"
#include "ash/shell_window_ids.h"
#include "ash/wm/system_modal_container_event_filter.h"
#include "ash/wm/window_animations.h"
#include "ash/wm/window_util.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/event.h"
#include "ui/aura/root_window.h"
#include "ui/aura/window.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/compositor/layer.h"
#include "ui/gfx/compositor/layer_animator.h"
#include "ui/gfx/compositor/scoped_layer_animation_settings.h"
#include "ui/views/view.h"
#include "ui/views/widget/widget.h"

namespace ash {
namespace internal {

namespace {

class ScreenView : public views::View {
 public:
  ScreenView() {}
  virtual ~ScreenView() {}

  // Overridden from views::View:
  virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
    canvas->FillRect(GetLocalBounds(), GetOverlayColor());
  }

 private:
  SkColor GetOverlayColor() {
    if (CommandLine::ForCurrentProcess()->HasSwitch(
            switches::kAuraGoogleDialogFrames)) {
      return SK_ColorWHITE;
    }
    return SK_ColorBLACK;
  }

  DISALLOW_COPY_AND_ASSIGN(ScreenView);
};

}  // namespace

////////////////////////////////////////////////////////////////////////////////
// SystemModalContainerLayoutManager, public:

SystemModalContainerLayoutManager::SystemModalContainerLayoutManager(
    aura::Window* container)
    : container_(container),
      modal_screen_(NULL),
      ALLOW_THIS_IN_INITIALIZER_LIST(modality_filter_(
          new SystemModalContainerEventFilter(this))) {
}

SystemModalContainerLayoutManager::~SystemModalContainerLayoutManager() {
}

////////////////////////////////////////////////////////////////////////////////
// SystemModalContainerLayoutManager, aura::LayoutManager implementation:

void SystemModalContainerLayoutManager::OnWindowResized() {
  if (modal_screen_) {
    modal_screen_->SetBounds(gfx::Rect(0, 0, container_->bounds().width(),
                                       container_->bounds().height()));
  }
}

void SystemModalContainerLayoutManager::OnWindowAddedToLayout(
    aura::Window* child) {
  DCHECK((modal_screen_ && child == modal_screen_->GetNativeView()) ||
         child->type() == aura::client::WINDOW_TYPE_NORMAL ||
         child->type() == aura::client::WINDOW_TYPE_POPUP);
  child->AddObserver(this);
  if (child->GetIntProperty(aura::client::kModalKey))
    AddModalWindow(child);
}

void SystemModalContainerLayoutManager::OnWillRemoveWindowFromLayout(
    aura::Window* child) {
  child->RemoveObserver(this);
  if (child->GetIntProperty(aura::client::kModalKey))
    RemoveModalWindow(child);
}

void SystemModalContainerLayoutManager::OnChildWindowVisibilityChanged(
    aura::Window* child,
    bool visible) {
}

void SystemModalContainerLayoutManager::SetChildBounds(
    aura::Window* child,
    const gfx::Rect& requested_bounds) {
  SetChildBoundsDirect(child, requested_bounds);
}

////////////////////////////////////////////////////////////////////////////////
// SystemModalContainerLayoutManager, aura::WindowObserver implementation:

void SystemModalContainerLayoutManager::OnWindowPropertyChanged(
    aura::Window* window,
    const char* key,
    void* old) {
  if (key != aura::client::kModalKey)
    return;

  if (window->GetIntProperty(aura::client::kModalKey)) {
    AddModalWindow(window);
  } else if (static_cast<int>(reinterpret_cast<intptr_t>(old))) {
    RemoveModalWindow(window);
  }
}

////////////////////////////////////////////////////////////////////////////////
// SystemModalContainerLayoutManager,
//     ui::ImplicitAnimationObserver implementation:

void SystemModalContainerLayoutManager::OnImplicitAnimationsCompleted() {
  if (modal_screen_ && !modal_screen_->GetNativeView()->layer()->ShouldDraw())
    DestroyModalScreen();
}

////////////////////////////////////////////////////////////////////////////////
// SystemModalContainerLayoutManager,
//     SystemModalContainerEventFilter::Delegate implementation:

bool SystemModalContainerLayoutManager::CanWindowReceiveEvents(
    aura::Window* window) {
  // This container can not handle events if the screen is locked and it is not
  // above the lock screen layer (crbug.com/110920).
  if (ash::Shell::GetInstance()->IsScreenLocked() &&
      container_->id() < ash::internal::kShellWindowId_LockScreenContainer)
    return true;
  return GetActivatableWindow(window) == modal_window();
}

////////////////////////////////////////////////////////////////////////////////
// SystemModalContainerLayoutManager, private:

void SystemModalContainerLayoutManager::AddModalWindow(aura::Window* window) {
  modal_windows_.push_back(window);
  CreateModalScreen();
}

void SystemModalContainerLayoutManager::RemoveModalWindow(
    aura::Window* window) {
  aura::Window::Windows::iterator it =
      std::find(modal_windows_.begin(), modal_windows_.end(), window);
  if (it != modal_windows_.end())
    modal_windows_.erase(it);

  if (modal_windows_.empty())
    HideModalScreen();
  else
    ash::ActivateWindow(modal_window());
}

void SystemModalContainerLayoutManager::CreateModalScreen() {
  if (modal_screen_)
    return;
  modal_screen_ = new views::Widget;
  views::Widget::InitParams params(views::Widget::InitParams::TYPE_CONTROL);
  params.parent = container_;
  params.bounds = gfx::Rect(0, 0, container_->bounds().width(),
                            container_->bounds().height());
  modal_screen_->Init(params);
  modal_screen_->GetNativeView()->SetName(
      "SystemModalContainerLayoutManager.ModalScreen");
  modal_screen_->SetContentsView(new ScreenView);
  modal_screen_->GetNativeView()->layer()->SetOpacity(0.0f);

  Shell::GetInstance()->AddRootWindowEventFilter(modality_filter_.get());

  StopObservingImplicitAnimations();

  ui::ScopedLayerAnimationSettings settings(
      modal_screen_->GetNativeView()->layer()->GetAnimator());
  settings.AddObserver(this);
  modal_screen_->Show();
  modal_screen_->GetNativeView()->layer()->SetOpacity(0.5f);
  container_->StackChildAtTop(modal_screen_->GetNativeView());
}

void SystemModalContainerLayoutManager::DestroyModalScreen() {
  // Stop observing the modal screen's animations.
  StopObservingImplicitAnimations();
  modal_screen_->Close();
  modal_screen_ = NULL;
}

void SystemModalContainerLayoutManager::HideModalScreen() {
  StopObservingImplicitAnimations();

  Shell::GetInstance()->RemoveRootWindowEventFilter(modality_filter_.get());
  ui::ScopedLayerAnimationSettings settings(
      modal_screen_->GetNativeView()->layer()->GetAnimator());
  settings.AddObserver(this);
  modal_screen_->GetNativeView()->layer()->SetOpacity(0.0f);
}

}  // namespace internal
}  // namespace ash
<commit_msg>ash: Fix creating the modal screen.<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ash/wm/system_modal_container_layout_manager.h"

#include "ash/ash_switches.h"
#include "ash/shell.h"
#include "ash/shell_window_ids.h"
#include "ash/wm/system_modal_container_event_filter.h"
#include "ash/wm/window_animations.h"
#include "ash/wm/window_util.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/event.h"
#include "ui/aura/root_window.h"
#include "ui/aura/window.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/compositor/layer.h"
#include "ui/gfx/compositor/layer_animator.h"
#include "ui/gfx/compositor/scoped_layer_animation_settings.h"
#include "ui/views/view.h"
#include "ui/views/widget/widget.h"

namespace ash {
namespace internal {

namespace {

class ScreenView : public views::View {
 public:
  ScreenView() {}
  virtual ~ScreenView() {}

  // Overridden from views::View:
  virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
    canvas->FillRect(GetLocalBounds(), GetOverlayColor());
  }

 private:
  SkColor GetOverlayColor() {
    if (CommandLine::ForCurrentProcess()->HasSwitch(
            switches::kAuraGoogleDialogFrames)) {
      return SK_ColorWHITE;
    }
    return SK_ColorBLACK;
  }

  DISALLOW_COPY_AND_ASSIGN(ScreenView);
};

}  // namespace

////////////////////////////////////////////////////////////////////////////////
// SystemModalContainerLayoutManager, public:

SystemModalContainerLayoutManager::SystemModalContainerLayoutManager(
    aura::Window* container)
    : container_(container),
      modal_screen_(NULL),
      ALLOW_THIS_IN_INITIALIZER_LIST(modality_filter_(
          new SystemModalContainerEventFilter(this))) {
}

SystemModalContainerLayoutManager::~SystemModalContainerLayoutManager() {
}

////////////////////////////////////////////////////////////////////////////////
// SystemModalContainerLayoutManager, aura::LayoutManager implementation:

void SystemModalContainerLayoutManager::OnWindowResized() {
  if (modal_screen_) {
    modal_screen_->SetBounds(gfx::Rect(0, 0, container_->bounds().width(),
                                       container_->bounds().height()));
  }
}

void SystemModalContainerLayoutManager::OnWindowAddedToLayout(
    aura::Window* child) {
  DCHECK((modal_screen_ && child == modal_screen_->GetNativeView()) ||
         child->type() == aura::client::WINDOW_TYPE_NORMAL ||
         child->type() == aura::client::WINDOW_TYPE_POPUP);
  child->AddObserver(this);
  if (child->GetIntProperty(aura::client::kModalKey))
    AddModalWindow(child);
}

void SystemModalContainerLayoutManager::OnWillRemoveWindowFromLayout(
    aura::Window* child) {
  child->RemoveObserver(this);
  if (child->GetIntProperty(aura::client::kModalKey))
    RemoveModalWindow(child);
}

void SystemModalContainerLayoutManager::OnChildWindowVisibilityChanged(
    aura::Window* child,
    bool visible) {
}

void SystemModalContainerLayoutManager::SetChildBounds(
    aura::Window* child,
    const gfx::Rect& requested_bounds) {
  SetChildBoundsDirect(child, requested_bounds);
}

////////////////////////////////////////////////////////////////////////////////
// SystemModalContainerLayoutManager, aura::WindowObserver implementation:

void SystemModalContainerLayoutManager::OnWindowPropertyChanged(
    aura::Window* window,
    const char* key,
    void* old) {
  if (key != aura::client::kModalKey)
    return;

  if (window->GetIntProperty(aura::client::kModalKey)) {
    AddModalWindow(window);
  } else if (static_cast<int>(reinterpret_cast<intptr_t>(old))) {
    RemoveModalWindow(window);
  }
}

////////////////////////////////////////////////////////////////////////////////
// SystemModalContainerLayoutManager,
//     ui::ImplicitAnimationObserver implementation:

void SystemModalContainerLayoutManager::OnImplicitAnimationsCompleted() {
  if (modal_screen_ && !modal_screen_->GetNativeView()->layer()->ShouldDraw())
    DestroyModalScreen();
}

////////////////////////////////////////////////////////////////////////////////
// SystemModalContainerLayoutManager,
//     SystemModalContainerEventFilter::Delegate implementation:

bool SystemModalContainerLayoutManager::CanWindowReceiveEvents(
    aura::Window* window) {
  // This container can not handle events if the screen is locked and it is not
  // above the lock screen layer (crbug.com/110920).
  if (ash::Shell::GetInstance()->IsScreenLocked() &&
      container_->id() < ash::internal::kShellWindowId_LockScreenContainer)
    return true;
  return GetActivatableWindow(window) == modal_window();
}

////////////////////////////////////////////////////////////////////////////////
// SystemModalContainerLayoutManager, private:

void SystemModalContainerLayoutManager::AddModalWindow(aura::Window* window) {
  modal_windows_.push_back(window);
  CreateModalScreen();
}

void SystemModalContainerLayoutManager::RemoveModalWindow(
    aura::Window* window) {
  aura::Window::Windows::iterator it =
      std::find(modal_windows_.begin(), modal_windows_.end(), window);
  if (it != modal_windows_.end())
    modal_windows_.erase(it);

  if (modal_windows_.empty())
    HideModalScreen();
  else
    ash::ActivateWindow(modal_window());
}

void SystemModalContainerLayoutManager::CreateModalScreen() {
  if (!modal_screen_) {
    modal_screen_ = new views::Widget;
    views::Widget::InitParams params(views::Widget::InitParams::TYPE_CONTROL);
    params.parent = container_;
    params.bounds = gfx::Rect(0, 0, container_->bounds().width(),
        container_->bounds().height());
    modal_screen_->Init(params);
    modal_screen_->GetNativeView()->SetName(
        "SystemModalContainerLayoutManager.ModalScreen");
    modal_screen_->SetContentsView(new ScreenView);
    modal_screen_->GetNativeView()->layer()->SetOpacity(0.0f);

    Shell::GetInstance()->AddRootWindowEventFilter(modality_filter_.get());
  }

  StopObservingImplicitAnimations();

  ui::ScopedLayerAnimationSettings settings(
      modal_screen_->GetNativeView()->layer()->GetAnimator());
  settings.AddObserver(this);
  modal_screen_->Show();
  modal_screen_->GetNativeView()->layer()->SetOpacity(0.5f);
  container_->StackChildAtTop(modal_screen_->GetNativeView());
}

void SystemModalContainerLayoutManager::DestroyModalScreen() {
  // Stop observing the modal screen's animations.
  StopObservingImplicitAnimations();
  modal_screen_->Close();
  modal_screen_ = NULL;
}

void SystemModalContainerLayoutManager::HideModalScreen() {
  StopObservingImplicitAnimations();

  Shell::GetInstance()->RemoveRootWindowEventFilter(modality_filter_.get());
  ui::ScopedLayerAnimationSettings settings(
      modal_screen_->GetNativeView()->layer()->GetAnimator());
  settings.AddObserver(this);
  modal_screen_->GetNativeView()->layer()->SetOpacity(0.0f);
}

}  // namespace internal
}  // namespace ash
<|endoftext|>


<commit_before>//-----------------------------------------------------------------------bl-
//--------------------------------------------------------------------------
//
// GRINS - General Reacting Incompressible Navier-Stokes
//
// Copyright (C) 2014-2015 Paul T. Bauman, Roy H. Stogner
// Copyright (C) 2010-2013 The PECOS Development Team
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the Version 2.1 GNU Lesser General
// Public License as published by the Free Software Foundation.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc. 51 Franklin Street, Fifth Floor,
// Boston, MA  02110-1301  USA
//
//-----------------------------------------------------------------------el-

// C++
#include <iostream>

// This class
#include "grins/grins_solver.h"

// GRINS
#include "grins/multiphysics_sys.h"

// libMesh
#include "libmesh/getpot.h"
#include "libmesh/fem_system.h"
#include "libmesh/diff_solver.h"

namespace GRINS
{

  Solver::Solver( const GetPot& input )
    : _max_nonlinear_iterations( input("linear-nonlinear-solver/max_nonlinear_iterations", 10 ) ),
      _continue_after_max_iterations( input("linear-nonlinear-solver/continue_after_max_iterations", false ) ),
      _relative_step_tolerance( input("linear-nonlinear-solver/relative_step_tolerance", 1.e-6 ) ),
      _absolute_step_tolerance( input("linear-nonlinear-solver/absolute_step_tolerance", 0.0 ) ),
      _relative_residual_tolerance( input("linear-nonlinear-solver/relative_residual_tolerance", 1.e-15 ) ),
      _absolute_residual_tolerance( input("linear-nonlinear-solver/absolute_residual_tolerance", 0.0 ) ),
      _initial_linear_tolerance( input("linear-nonlinear-solver/initial_linear_tolerance", 1.e-3 ) ),
      _minimum_linear_tolerance( input("linear-nonlinear-solver/minimum_linear_tolerance", 1.e-3 ) ),
      _max_linear_iterations( input("linear-nonlinear-solver/max_linear_iterations", 500 ) ),
      _continue_after_backtrack_failure( input("linear-nonlinear-solver/continue_after_backtrack_failure", false ) ),
      _solver_quiet( input("screen-options/solver_quiet", false ) ),
      _solver_verbose( input("screen-options/solver_verbose", false ) )
  {
    return;
  }

  Solver::~Solver()
  {
    return;
  }

  void Solver::initialize( const GetPot& /*input*/,
			   std::tr1::shared_ptr<libMesh::EquationSystems> equation_system,
			   MultiphysicsSystem* system )
  {

    // Defined in subclasses depending on the solver used.
    this->init_time_solver(system);

    // Initialize the system
    equation_system->init();

    // Get diff solver to set options
    libMesh::DiffSolver &solver = *(system->time_solver->diff_solver().get());

    // Set linear/nonlinear solver options
    this->set_solver_options( solver );

    return;
  }

  void Solver::set_solver_options( libMesh::DiffSolver& solver  )
  {
    solver.quiet                       = this->_solver_quiet;
    solver.verbose                     = this->_solver_verbose;
    solver.max_nonlinear_iterations    = this->_max_nonlinear_iterations;
    solver.relative_step_tolerance     = this->_relative_step_tolerance;
    solver.absolute_step_tolerance     = this->_absolute_step_tolerance;
    solver.relative_residual_tolerance = this->_relative_residual_tolerance;
    solver.absolute_residual_tolerance = this->_absolute_residual_tolerance;
    solver.max_linear_iterations       = this->_max_linear_iterations;
    solver.continue_after_backtrack_failure = this->_continue_after_backtrack_failure;
    solver.initial_linear_tolerance    = this->_initial_linear_tolerance;
    solver.minimum_linear_tolerance    = this->_minimum_linear_tolerance;
    solver.continue_after_max_iterations    = this->_continue_after_max_iterations;

    return;
  }

} // namespace GRINS
<commit_msg>[grins]: fixing member variables init order<commit_after>//-----------------------------------------------------------------------bl-
//--------------------------------------------------------------------------
//
// GRINS - General Reacting Incompressible Navier-Stokes
//
// Copyright (C) 2014-2015 Paul T. Bauman, Roy H. Stogner
// Copyright (C) 2010-2013 The PECOS Development Team
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the Version 2.1 GNU Lesser General
// Public License as published by the Free Software Foundation.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc. 51 Franklin Street, Fifth Floor,
// Boston, MA  02110-1301  USA
//
//-----------------------------------------------------------------------el-

// C++
#include <iostream>

// This class
#include "grins/grins_solver.h"

// GRINS
#include "grins/multiphysics_sys.h"

// libMesh
#include "libmesh/getpot.h"
#include "libmesh/fem_system.h"
#include "libmesh/diff_solver.h"

namespace GRINS
{

  Solver::Solver( const GetPot& input )
    : _max_nonlinear_iterations( input("linear-nonlinear-solver/max_nonlinear_iterations", 10 ) ),
      _relative_step_tolerance( input("linear-nonlinear-solver/relative_step_tolerance", 1.e-6 ) ),
      _absolute_step_tolerance( input("linear-nonlinear-solver/absolute_step_tolerance", 0.0 ) ),
      _relative_residual_tolerance( input("linear-nonlinear-solver/relative_residual_tolerance", 1.e-15 ) ),
      _absolute_residual_tolerance( input("linear-nonlinear-solver/absolute_residual_tolerance", 0.0 ) ),
      _initial_linear_tolerance( input("linear-nonlinear-solver/initial_linear_tolerance", 1.e-3 ) ),
      _minimum_linear_tolerance( input("linear-nonlinear-solver/minimum_linear_tolerance", 1.e-3 ) ),
      _max_linear_iterations( input("linear-nonlinear-solver/max_linear_iterations", 500 ) ),
      _continue_after_backtrack_failure( input("linear-nonlinear-solver/continue_after_backtrack_failure", false ) ),
      _continue_after_max_iterations( input("linear-nonlinear-solver/continue_after_max_iterations", false ) ),
      _solver_quiet( input("screen-options/solver_quiet", false ) ),
      _solver_verbose( input("screen-options/solver_verbose", false ) )
  {
    return;
  }

  Solver::~Solver()
  {
    return;
  }

  void Solver::initialize( const GetPot& /*input*/,
			   std::tr1::shared_ptr<libMesh::EquationSystems> equation_system,
			   MultiphysicsSystem* system )
  {

    // Defined in subclasses depending on the solver used.
    this->init_time_solver(system);

    // Initialize the system
    equation_system->init();

    // Get diff solver to set options
    libMesh::DiffSolver &solver = *(system->time_solver->diff_solver().get());

    // Set linear/nonlinear solver options
    this->set_solver_options( solver );

    return;
  }

  void Solver::set_solver_options( libMesh::DiffSolver& solver  )
  {
    solver.quiet                       = this->_solver_quiet;
    solver.verbose                     = this->_solver_verbose;
    solver.max_nonlinear_iterations    = this->_max_nonlinear_iterations;
    solver.relative_step_tolerance     = this->_relative_step_tolerance;
    solver.absolute_step_tolerance     = this->_absolute_step_tolerance;
    solver.relative_residual_tolerance = this->_relative_residual_tolerance;
    solver.absolute_residual_tolerance = this->_absolute_residual_tolerance;
    solver.max_linear_iterations       = this->_max_linear_iterations;
    solver.continue_after_backtrack_failure = this->_continue_after_backtrack_failure;
    solver.initial_linear_tolerance    = this->_initial_linear_tolerance;
    solver.minimum_linear_tolerance    = this->_minimum_linear_tolerance;
    solver.continue_after_max_iterations    = this->_continue_after_max_iterations;

    return;
  }

} // namespace GRINS
<|endoftext|>


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

Licensed to the OpenCOR team under one or more contributor license agreements.
See the NOTICE.txt file distributed with this work for additional information
regarding copyright ownership. The OpenCOR team licenses this file to you 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.

*******************************************************************************/

//==============================================================================
// CLI utilities
//==============================================================================

#include "cliapplication.h"
#include "cliutils.h"
#include "settings.h"

//==============================================================================

#include <QCoreApplication>
#include <QDir>
#include <QFileInfo>
#include <QNetworkAccessManager>
#include <QNetworkInterface>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QProcess>
#include <QResource>
#include <QSettings>
#include <QTemporaryFile>
#include <QXmlStreamReader>

//==============================================================================

namespace OpenCOR {

//==============================================================================

#include "corecliutils.cpp.inl"

//==============================================================================

void initQtMessagePattern()
{
    // We don't want to see debug/warning messages when not in debug mode

#ifndef QT_DEBUG
    qSetMessagePattern("%{if-debug}%{endif}"
                       "%{if-warning}%{endif}"
                       "%{if-critical}%{message}%{endif}"
                       "%{if-fatal}%{message}%{endif}");
#endif
}

//==============================================================================

void initPluginsPath(const QString &pAppFileName)
{
    // Initialise the plugins path

    QFileInfo appFileInfo = pAppFileName;
    QString appDir;

#ifdef Q_OS_WIN
    if (appFileInfo.completeSuffix().isEmpty()) {
        // If pAppFileName has no suffix, then it means that we tried to run
        // OpenCOR using something like "[OpenCOR]/OpenCOR", in which case
        // QFileInfo() will be lost when trying to retrieve the canonical path
        // for OpenCOR. Now, when we use something like "[OpenCOR]/OpenCOR",
        // it's as if we were to use something like "[OpenCOR]/OpenCOR.com", so
        // update appFileInfo accordingly

        appFileInfo = pAppFileName+".com";
    }
#endif

    appDir = nativeCanonicalDirName(appFileInfo.canonicalPath());

    QString pluginsDir = QString();

#if defined(Q_OS_WIN) || defined(Q_OS_LINUX)
    pluginsDir = appDir+QDir::separator()+QString("..")+QDir::separator()+"plugins";

    if (!QDir(pluginsDir).exists()) {
        // The plugins directory doesn't exist, which should only happen if we
        // are trying to run OpenCOR from within Qt Creator, in which case
        // OpenCOR's file name will be [OpenCOR]/build/OpenCOR.exe rather than
        // [OpenCOR]/build/bin/OpenCOR.exe as it should normally be if we were
        // to mimic the case where OpenCOR has been deployed. Then, because the
        // plugins are in [OpenCOR]/build/plugins/OpenCOR, we must skip the
        // "../" bit. So, yes, it's not neat, but is there another solution?...

        pluginsDir = appDir+QDir::separator()+"plugins";
    }
#elif defined(Q_OS_MAC)
    pluginsDir = appDir+QDir::separator()+QString("..")+QDir::separator()+"PlugIns";
#else
    #error Unsupported platform
#endif

    QCoreApplication::setLibraryPaths(QStringList() << nativeCanonicalDirName(pluginsDir));
}

//==============================================================================

void initApplication(QString *pAppDate)
{
    // Remove our global settings, in case OpenCOR previously crashed or
    // something (and therefore didn't remove all of them before quitting)

    removeGlobalSettings();

    // Ignore SSL-related warnings
    // Note #1: this is to address an issue with QSslSocket not being able to
    //          resolve some methods...
    // Note #2: see issue #516 for more information...

    qputenv("QT_LOGGING_RULES", "qt.network.ssl.warning=false");

    // Customise our application a bit
    // Note: on OS X, the orgnisation domain allows our settings file to respect
    //       the way things are done on that operating system while it's not
    //       useful on Windows and Linux (and, in fact, messes things up a
    //       bit)...

    qApp->setApplicationName("OpenCOR");
#ifdef Q_OS_MAC
    qApp->setOrganizationDomain("opencor.ws");
#endif

    // Retrieve and set the version of the application

    QString versionData;

    readTextFromFile(":app_versiondate", versionData);

    QStringList versionDataList = versionData.split(eolString());

    qApp->setApplicationVersion(versionDataList.first());

    if (pAppDate)
        *pAppDate = versionDataList.last();
}

//==============================================================================

bool cliApplication(int *pRes)
{
    // Create and run our CLI application object

    CliApplication *cliApp = new CliApplication();

    bool res = cliApp->run(pRes);

    delete cliApp;

    return res;
}

//==============================================================================

QString applicationDescription(const bool &pGuiMode)
{
    QString res = QObject::tr("%1 is a cross-platform modelling environment, which can be used to organise, edit, simulate and analyse CellML files.").arg(""+qAppName()+"");

    return pGuiMode?res:plainString(res);
}

//==============================================================================

QString applicationBuildInformation(const bool &pGuiMode)
{
    QString res = QObject::tr("This version of %1 was built using Qt %2.").arg(""+qAppName()+"", qVersion());

    return pGuiMode?res:plainString(res);
}

//==============================================================================

void removeGlobalSettings()
{
    // Remove the global settings shared between OpenCOR and its different
    // plugins

    QSettings settings;

    settings.remove(qGlobalSettings);
}

//==============================================================================

}   // namespace OpenCOR

//==============================================================================
// End of file
//==============================================================================
<commit_msg>Some minor cleaning up [ci skip].<commit_after>/*******************************************************************************

Licensed to the OpenCOR team under one or more contributor license agreements.
See the NOTICE.txt file distributed with this work for additional information
regarding copyright ownership. The OpenCOR team licenses this file to you 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.

*******************************************************************************/

//==============================================================================
// CLI utilities
//==============================================================================

#include "cliapplication.h"
#include "cliutils.h"
#include "settings.h"

//==============================================================================

#include <QCoreApplication>
#include <QDir>
#include <QFileInfo>
#include <QNetworkAccessManager>
#include <QNetworkInterface>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QProcess>
#include <QResource>
#include <QSettings>
#include <QTemporaryFile>
#include <QXmlStreamReader>

//==============================================================================

namespace OpenCOR {

//==============================================================================

#include "corecliutils.cpp.inl"

//==============================================================================

void initQtMessagePattern()
{
    // We don't want to see debug/warning messages when not in debug mode

#ifndef QT_DEBUG
    qSetMessagePattern("%{if-debug}%{endif}"
                       "%{if-warning}%{endif}"
                       "%{if-critical}%{message}%{endif}"
                       "%{if-fatal}%{message}%{endif}");
#endif
}

//==============================================================================

void initPluginsPath(const QString &pAppFileName)
{
    // Initialise the plugins path

    QFileInfo appFileInfo = pAppFileName;
    QString appDir;

#ifdef Q_OS_WIN
    if (appFileInfo.completeSuffix().isEmpty()) {
        // If pAppFileName has no suffix, then it means that we tried to run
        // OpenCOR using something like "[OpenCOR]/OpenCOR", in which case
        // QFileInfo() will be lost when trying to retrieve the canonical path
        // for OpenCOR. Now, when we use something like "[OpenCOR]/OpenCOR",
        // it's as if we were to use something like "[OpenCOR]/OpenCOR.com", so
        // update appFileInfo accordingly

        appFileInfo = pAppFileName+".com";
    }
#endif

    appDir = nativeCanonicalDirName(appFileInfo.canonicalPath());

    QString pluginsDir = QString();

#if defined(Q_OS_WIN) || defined(Q_OS_LINUX)
    pluginsDir = appDir+QDir::separator()+QString("..")+QDir::separator()+"plugins";

    if (!QDir(pluginsDir).exists()) {
        // The plugins directory doesn't exist, which should only happen if we
        // are trying to run OpenCOR from within Qt Creator, in which case
        // OpenCOR's file name will be [OpenCOR]/build/OpenCOR.exe rather than
        // [OpenCOR]/build/bin/OpenCOR.exe as it should normally be if we were
        // to mimic the case where OpenCOR has been deployed. Then, because the
        // plugins are in [OpenCOR]/build/plugins/OpenCOR, we must skip the
        // "../" bit. So, yes, it's not neat, but is there another solution?...

        pluginsDir = appDir+QDir::separator()+"plugins";
    }
#elif defined(Q_OS_MAC)
    pluginsDir = appDir+QDir::separator()+QString("..")+QDir::separator()+"PlugIns";
#else
    #error Unsupported platform
#endif

    QCoreApplication::setLibraryPaths(QStringList() << nativeCanonicalDirName(pluginsDir));
}

//==============================================================================

void initApplication(QString *pAppDate)
{
    // Remove our global settings, in case OpenCOR previously crashed or
    // something (and therefore didn't remove all of them before quitting)

    removeGlobalSettings();

    // Ignore SSL-related warnings
    // Note #1: this is to address an issue with QSslSocket not being able to
    //          resolve some methods...
    // Note #2: see issue #516 for more information...

    qputenv("QT_LOGGING_RULES", "qt.network.ssl.warning=false");

    // Set the organisation and application names of our application

    qApp->setOrganizationName("Physiome");
    qApp->setApplicationName("OpenCOR");

    // Retrieve and set the version of the application

    QString versionData;

    readTextFromFile(":app_versiondate", versionData);

    QStringList versionDataList = versionData.split(eolString());

    qApp->setApplicationVersion(versionDataList.first());

    if (pAppDate)
        *pAppDate = versionDataList.last();
}

//==============================================================================

bool cliApplication(int *pRes)
{
    // Create and run our CLI application object

    CliApplication *cliApp = new CliApplication();

    bool res = cliApp->run(pRes);

    delete cliApp;

    return res;
}

//==============================================================================

QString applicationDescription(const bool &pGuiMode)
{
    QString res = QObject::tr("%1 is a cross-platform modelling environment, which can be used to organise, edit, simulate and analyse CellML files.").arg(""+qAppName()+"");

    return pGuiMode?res:plainString(res);
}

//==============================================================================

QString applicationBuildInformation(const bool &pGuiMode)
{
    QString res = QObject::tr("This version of %1 was built using Qt %2.").arg(""+qAppName()+"", qVersion());

    return pGuiMode?res:plainString(res);
}

//==============================================================================

void removeGlobalSettings()
{
    // Remove the global settings shared between OpenCOR and its different
    // plugins

    QSettings settings;

    settings.remove(qGlobalSettings);
}

//==============================================================================

}   // namespace OpenCOR

//==============================================================================
// End of file
//==============================================================================
<|endoftext|>


<commit_before>// vim:ts=2:sw=2:expandtab:autoindent:filetype=cpp:
#include "flusspferd/importer.hpp"
#include "flusspferd/create.hpp"
#include "flusspferd/string.hpp"

#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <errno.h>

// Wrap the windows calls to the *nix equivalents
#ifndef _WIN32
#include <dlfcn.h>

#define DIRSEP1 "/"
#define DIRSEP2 ""
#define SHLIBPREFIX "lib"

#ifdef APPLE
#define SHLIBSUFFIX ".dylib"
#else
#define SHLIBSUFFIX ".so"
#endif

#else

#include <windows.h>

#define DIRSEP1 "\\"
#define DIRSEP2 "/"
#define SHLIBPREFIX 0
#define SHLIBSUFFIX ".dll"

#define dlopen(x,y) (void*)LoadLibrary(x)
#define dlsym(x,y) (void*)GetProcAddress((HMODULE)x,y)
#define dlclose(x) FreeLibrary((HMODULE)x)

// FIXME - not thread safe?
const char *dlerror() {
  static char szMsgBuf[256];
  ::FormatMessage(
      FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
      NULL,
      ::GetLastError(),
      MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
      szMsgBuf,
      sizeof szMsgBuf,
      NULL);
  return szMsgBuf;
}

#endif

using namespace flusspferd;

object importer::class_info::create_prototype() {
  object proto = create_object();

  return proto;
}

importer::importer(call_context &) {
}

importer::~importer() {
}

void importer::post_initialize() {
  // Create the load method on the actual object itself, not on the prototype
  // That way the following works:
  //
  // i.load('foo'); // Assume foo module defines this.foo = 'abc'
  // print(i.foo); // abc
  //
  // without the problem of load being overridden to do bad things
  add_native_method( "load", 2);
  register_native_method("load", &importer::load);

  // Store search paths
  set_property("paths", create_array());

  // Create a context object, which is the object on which all modules are
  // evaluated
  object context = create_object();
  set_property("context", context);

  // this.contexnt.__proto__ = this.__proto__;
  // Not sure we actually want to do this, but we can for now.
  context.set_prototype(get_prototype());
  set_prototype(context);
}

value importer::load(string const &name, bool binary_only) {
  std::string so_name, js_name;
  so_name = process_name(name);
  js_name = process_name(name, true);

  //TODO: I'd like a version that throws an exception instead of assert traps
  value paths_v = get_property("paths").to_object();
  if (!paths_v.is_object())
    throw exception("Unable to get search paths or its not an object");

  array paths = paths_v.get_object();

  // TODO: We could probably do with an array class.
  size_t len = paths.get_length();
  for (size_t i=0; i < len; i++) {
    std::string path = paths.get_element(i).to_string().to_string();
    std::string fullpath = path + js_name;

    if (!binary_only) {
      std::ifstream file(fullpath.c_str(), std::ios::in | std::ios::binary);

      if (file.good()) {
        // Execute the file
        std::stringstream cbuf;
        cbuf << file.rdbuf();
        if (!file)
          // TODO: Is the information (fullpath) leak bad?
          throw exception( std::string("Error reading from ") + fullpath );

        // Execute the file
        std::string contents = cbuf.str();
        return get_current_context().evaluateInScope(contents.data(),
            contents.size(), fullpath.c_str(), 1,
            get_property("context").to_object());
      }
    }

    fullpath = path + so_name;
    // Load the .so
    std::ifstream file(fullpath.c_str(), std::ios::in | std::ios::binary);

    if (file.good()) {
      // Use file open as an exists check
      file.close();

      void *handle = dlopen(fullpath.c_str(), RTLD_LAZY);
      if (!handle) {
        std::stringstream ss;
        ss << "Unable to load library '" << fullpath.c_str() << "': " << dlerror();
        throw exception(ss.str());
      }

      value (*func)(object container);
      if (!(func = reinterpret_cast<value (*)(object)>(dlsym(handle, "flusspferd_load")))) {
        std::stringstream ss;
        ss << "Unable to load library '" << fullpath.c_str() << "': " << dlerror();
        throw exception(ss.str());
      }

      // TODO: We should probably track and close the dlopen
      return func(get_property("context").to_object());
    }
  }

  // We probably want to throw an exception here.
  std::stringstream ss;
  ss << "Unable to find library '";
  ss << name.c_str();
  ss << "' in [";
  ss << paths_v.to_string().c_str() << "]";
  throw exception(ss.str());
}

// Take 'foo.bar' as a flusspferd::string, check no path sep in it, and
// return '/foo/bar.js' or '/foo/libbar.so', etc. as a std::string
std::string importer::process_name(string const &name, bool for_script) {
  std::string p = name.to_string();

  if (p.find(DIRSEP1, 0) != std::string::npos &&
      p.find(DIRSEP2, 0) != std::string::npos) {
    throw exception("Path seperator not allowed in module name");
  }

  unsigned int pos = 0;
  while ( (pos = p.find('.', pos)) != std::string::npos) {
    p.replace(pos, 1, DIRSEP1);
    pos++;
  }

  if (!for_script && SHLIBPREFIX) {
    // stick the lib on the front as needed
    pos = p.rfind(DIRSEP1, 0);
    if (pos == std::string::npos)
      pos = 0;
    p.insert(pos, SHLIBPREFIX);
  }

  p = DIRSEP1 + p;
  if (for_script)
    p += ".js";
  else
    p += SHLIBSUFFIX;

  return p;

}

<commit_msg>Importer: style and line length<commit_after>// vim:ts=2:sw=2:expandtab:autoindent:filetype=cpp:
#include "flusspferd/importer.hpp"
#include "flusspferd/create.hpp"
#include "flusspferd/string.hpp"

#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <errno.h>

// Wrap the windows calls to the *nix equivalents
#ifndef _WIN32
#include <dlfcn.h>

#define DIRSEP1 "/"
#define DIRSEP2 ""
#define SHLIBPREFIX "lib"

#ifdef APPLE
#define SHLIBSUFFIX ".dylib"
#else
#define SHLIBSUFFIX ".so"
#endif

#else

#include <windows.h>

#define DIRSEP1 "\\"
#define DIRSEP2 "/"
#define SHLIBPREFIX 0
#define SHLIBSUFFIX ".dll"

#define dlopen(x,y) (void*)LoadLibrary(x)
#define dlsym(x,y) (void*)GetProcAddress((HMODULE)x,y)
#define dlclose(x) FreeLibrary((HMODULE)x)

// FIXME - not thread safe?
const char *dlerror() {
  static char szMsgBuf[256];
  ::FormatMessage(
      FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
      NULL,
      ::GetLastError(),
      MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
      szMsgBuf,
      sizeof szMsgBuf,
      NULL);
  return szMsgBuf;
}

#endif

using namespace flusspferd;

object importer::class_info::create_prototype() {
  object proto = create_object();
  return proto;
}

importer::importer(call_context &) {
}

importer::~importer() {}

void importer::post_initialize() {
  // Create the load method on the actual object itself, not on the prototype
  // That way the following works:
  //
  // i.load('foo'); // Assume foo module defines this.foo = 'abc'
  // print(i.foo); // abc
  //
  // without the problem of load being overridden to do bad things
  add_native_method("load", 2);
  register_native_method("load", &importer::load);

  // Store search paths
  set_property("paths", create_array());

  // Create a context object, which is the object on which all modules are
  // evaluated
  object context = create_object();
  set_property("context", context);

  // this.contexnt.__proto__ = this.__proto__;
  // Not sure we actually want to do this, but we can for now.
  context.set_prototype(get_prototype());
  set_prototype(context);
}

value importer::load(string const &name, bool binary_only) {
  std::string so_name, js_name;
  so_name = process_name(name);
  js_name = process_name(name, true);

  //TODO: I'd like a version that throws an exception instead of assert traps
  value paths_v = get_property("paths").to_object();
  if (!paths_v.is_object())
    throw exception("Unable to get search paths or its not an object");

  array paths = paths_v.get_object();

  // TODO: We could probably do with an array class.
  size_t len = paths.get_length();
  for (size_t i=0; i < len; i++) {
    std::string path = paths.get_element(i).to_string().to_string();
    std::string fullpath = path + js_name;

    if (!binary_only) {
      std::ifstream file(fullpath.c_str(), std::ios::in | std::ios::binary);

      if (file.good()) {
        // Execute the file
        std::stringstream cbuf;
        cbuf << file.rdbuf();
        if (!file)
          // TODO: Is the information (fullpath) leak bad?
          throw exception( std::string("Error reading from ") + fullpath );

        // Execute the file
        std::string contents = cbuf.str();
        return get_current_context().evaluateInScope(contents.data(),
            contents.size(), fullpath.c_str(), 1,
            get_property("context").to_object());
      }
    }

    fullpath = path + so_name;
    // Load the .so
    std::ifstream file(fullpath.c_str(), std::ios::in | std::ios::binary);

    if (file.good()) {
      // Use file open as an exists check
      file.close();

      void *handle = dlopen(fullpath.c_str(), RTLD_LAZY);
      if (!handle) {
        std::stringstream ss;
        ss << "Unable to load library '" << fullpath.c_str() << "': " << dlerror();
        throw exception(ss.str());
      }

      value (*func)(object container);
      func = (value (*)(object)) dlsym(handle, "flusspferd_load");
      if (func) {
        std::stringstream ss;
        ss << "Unable to load library '" << fullpath.c_str()
           << "': " << dlerror();
        throw exception(ss.str());
      }

      // TODO: We should probably track and close the dlopen
      return func(get_property("context").to_object());
    }
  }

  // We probably want to throw an exception here.
  std::stringstream ss;
  ss << "Unable to find library '";
  ss << name.c_str();
  ss << "' in [";
  ss << paths_v.to_string().c_str() << "]";
  throw exception(ss.str());
}

// Take 'foo.bar' as a flusspferd::string, check no path sep in it, and
// return '/foo/bar.js' or '/foo/libbar.so', etc. as a std::string
std::string importer::process_name(string const &name, bool for_script) {
  std::string p = name.to_string();

  if (p.find(DIRSEP1, 0) != std::string::npos &&
      p.find(DIRSEP2, 0) != std::string::npos) {
    throw exception("Path seperator not allowed in module name");
  }

  unsigned int pos = 0;
  while ( (pos = p.find('.', pos)) != std::string::npos) {
    p.replace(pos, 1, DIRSEP1);
    pos++;
  }

  if (!for_script && SHLIBPREFIX) {
    // stick the lib on the front as needed
    pos = p.rfind(DIRSEP1, 0);
    if (pos == std::string::npos)
      pos = 0;
    p.insert(pos, SHLIBPREFIX);
  }

  p = DIRSEP1 + p;
  if (for_script)
    p += ".js";
  else
    p += SHLIBSUFFIX;

  return p;
}

<|endoftext|>


<commit_before>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdint.h>
#include <errno.h>
#include <fcntl.h>

#include "util.h"
#include "linesrc.h"
#include "linesink.h"

#include <stdexcept>

using namespace std;

static string                   in_file = "-";
static string                   out_file = "-";

static haxpp_linesink           out_ls;

class haxpp_linesourcestack {
    public:
        haxpp_linesourcestack();
        ~haxpp_linesourcestack();
    public:
        void                        allocstack();
        void                        freestack();
        void                        push();
        void                        pop();
        haxpp_linesource&           top();
        const haxpp_linesource&     top() const;
        void                        clear();
        bool                        empty() const;
    private:
        static constexpr size_t     max_source_stack_default = 64;
        size_t                      max_source_stack = max_source_stack_default;
    private:
        haxpp_linesource*           in_ls = NULL;
        ssize_t                     in_ls_sp = -1;
};

haxpp_linesourcestack::haxpp_linesourcestack() {
}

haxpp_linesourcestack::~haxpp_linesourcestack() {
    freestack();
}

void haxpp_linesourcestack::allocstack() {
    if (in_ls == NULL) {
        in_ls = new haxpp_linesource[max_source_stack];
        in_ls_sp = -1;
    }
}

void haxpp_linesourcestack::freestack() {
    if (in_ls != NULL) {
        clear();
        delete[] in_ls;
        in_ls = NULL;
    }
    in_ls_sp = -1;
}

void haxpp_linesourcestack::push() {
    allocstack();

    /* NTS: when in_ls_sp == -1, in_ls_sp+1 == 0 */
    if (size_t(in_ls_sp+1) < max_source_stack)
        in_ls_sp++;
    else
        throw overflow_error("linesourcestack overflow");
}

void haxpp_linesourcestack::pop() {
    /* in_ls_sp >= 0 should mean in_ls != NULL or else this code would not permit in_ls_sp >= 0 */
    if (in_ls_sp >= ssize_t(0))
        in_ls[in_ls_sp--].close();
    else
        throw underflow_error("linesourcestack underflow");
}

haxpp_linesource& haxpp_linesourcestack::top() {
    /* in_ls_sp >= 0 should mean in_ls != NULL or else this code would not permit in_ls_sp >= 0 */
    if (in_ls_sp >= ssize_t(0))
        return in_ls[in_ls_sp];

    throw underflow_error("linesourcestack attempt to read top() when empty");
}

const haxpp_linesource& haxpp_linesourcestack::top() const {
    /* in_ls_sp >= 0 should mean in_ls != NULL or else this code would not permit in_ls_sp >= 0 */
    if (in_ls_sp >= ssize_t(0))
        return in_ls[in_ls_sp];

    throw underflow_error("linesourcestack attempt to read top() when empty");
}

void haxpp_linesourcestack::clear() {
    while (!empty()) pop();
}

bool haxpp_linesourcestack::empty() const {
    /* in_ls_sp >= 0 should mean in_ls != NULL or else this code would not permit in_ls_sp >= 0 */
    return (in_ls_sp == ssize_t(-1));
}

static haxpp_linesourcestack    in_lstk;

static void help() {
    fprintf(stderr,"haxpp infile outfile\n");
}

static int parse_argv(int argc,char **argv) {
    int nwac=0;
    char *a;
    int i=1;

    while (i < argc) {
        a = argv[i++];

        if (*a == '-' && strcmp(a,"-") != 0/*not "-"*/) {
            do { a++; } while (*a == '-');

            if (!strcmp(a,"h") || !strcmp(a,"help")) {
                help();
                return 1;
            }
            else {
                fprintf(stderr,"Unknown switch %s\n",a);
                return 1;
            }
        }
        else {
            switch (nwac++) {
                case 0:
                    in_file = a;
                    break;
                case 1:
                    out_file = a;
                    break;
                default:
                    fprintf(stderr,"Unexpected arg %s\n",a);
                    return 1;
            }
        }
    }

    return 0;
}

void send_line(haxpp_linesink &ls,const string &name,const linecount_t line) {
    string msg = string("#line ") + to_string(line) + " \"" + name + "\"";
    ls.write(msg.c_str());
}

int main(int argc,char **argv) {
    if (parse_argv(argc,argv))
        return 1;

    in_lstk.push();
    if (in_file == "-")
        in_lstk.top().setsource(stdin);
    else
        in_lstk.top().setsource(in_file);

    if (!in_lstk.top().open()) {
        fprintf(stderr,"Unable to open infile, %s\n",strerror(errno));
        return 1;
    }

    if (out_file == "-")
        out_ls.setsink(stdout);
    else
        out_ls.setsink(out_file);

    if (!out_ls.open()) {
        fprintf(stderr,"Unable to open outfile, %s\n",strerror(errno));
        return 1;
    }
    send_line(out_ls,in_lstk.top().getsourcename(),1);

    while (!in_lstk.top().eof()) {
        char *line = in_lstk.top().readline();
        if (line == nullptr) {
            if (!in_lstk.top().error() && in_lstk.top().eof()) {
                in_lstk.pop();
                if (in_lstk.empty())
                    break;
                else
                    continue;
            }
            else {
                fprintf(stderr,"Problem reading. error=%u eof=%u errno=%s\n",in_lstk.top().error(),in_lstk.top().eof(),strerror(errno));
                return 1;
            }
        }

        if (!out_ls.write(line)) {
            fprintf(stderr,"Error writing output\n");
            return 1;
        }
    }

    if (!in_lstk.empty()) {
        if (in_lstk.top().error()) {
            fprintf(stderr,"An error occurred while parsing %s\n",in_lstk.top().getsourcename().c_str());
            return 1;
        }
    }

    if (out_ls.error()) {
        fprintf(stderr,"An error occurred while parsing %s\n",out_ls.getsinkname().c_str());
        return 1;
    }

    out_ls.close();
    in_lstk.clear();
    return 0;
}

<commit_msg>Preprocessor parsing, begin<commit_after>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdint.h>
#include <errno.h>
#include <fcntl.h>

#include "util.h"
#include "linesrc.h"
#include "linesink.h"

#include <stdexcept>

using namespace std;

static string                   in_file = "-";
static string                   out_file = "-";

static haxpp_linesink           out_ls;

class haxpp_linesourcestack {
    public:
        haxpp_linesourcestack();
        ~haxpp_linesourcestack();
    public:
        void                        allocstack();
        void                        freestack();
        void                        push();
        void                        pop();
        haxpp_linesource&           top();
        const haxpp_linesource&     top() const;
        void                        clear();
        bool                        empty() const;
    private:
        static constexpr size_t     max_source_stack_default = 64;
        size_t                      max_source_stack = max_source_stack_default;
    private:
        haxpp_linesource*           in_ls = NULL;
        ssize_t                     in_ls_sp = -1;
};

haxpp_linesourcestack::haxpp_linesourcestack() {
}

haxpp_linesourcestack::~haxpp_linesourcestack() {
    freestack();
}

void haxpp_linesourcestack::allocstack() {
    if (in_ls == NULL) {
        in_ls = new haxpp_linesource[max_source_stack];
        in_ls_sp = -1;
    }
}

void haxpp_linesourcestack::freestack() {
    if (in_ls != NULL) {
        clear();
        delete[] in_ls;
        in_ls = NULL;
    }
    in_ls_sp = -1;
}

void haxpp_linesourcestack::push() {
    allocstack();

    /* NTS: when in_ls_sp == -1, in_ls_sp+1 == 0 */
    if (size_t(in_ls_sp+1) < max_source_stack)
        in_ls_sp++;
    else
        throw overflow_error("linesourcestack overflow");
}

void haxpp_linesourcestack::pop() {
    /* in_ls_sp >= 0 should mean in_ls != NULL or else this code would not permit in_ls_sp >= 0 */
    if (in_ls_sp >= ssize_t(0))
        in_ls[in_ls_sp--].close();
    else
        throw underflow_error("linesourcestack underflow");
}

haxpp_linesource& haxpp_linesourcestack::top() {
    /* in_ls_sp >= 0 should mean in_ls != NULL or else this code would not permit in_ls_sp >= 0 */
    if (in_ls_sp >= ssize_t(0))
        return in_ls[in_ls_sp];

    throw underflow_error("linesourcestack attempt to read top() when empty");
}

const haxpp_linesource& haxpp_linesourcestack::top() const {
    /* in_ls_sp >= 0 should mean in_ls != NULL or else this code would not permit in_ls_sp >= 0 */
    if (in_ls_sp >= ssize_t(0))
        return in_ls[in_ls_sp];

    throw underflow_error("linesourcestack attempt to read top() when empty");
}

void haxpp_linesourcestack::clear() {
    while (!empty()) pop();
}

bool haxpp_linesourcestack::empty() const {
    /* in_ls_sp >= 0 should mean in_ls != NULL or else this code would not permit in_ls_sp >= 0 */
    return (in_ls_sp == ssize_t(-1));
}

static haxpp_linesourcestack    in_lstk;

static void help() {
    fprintf(stderr,"haxpp infile outfile\n");
}

static int parse_argv(int argc,char **argv) {
    int nwac=0;
    char *a;
    int i=1;

    while (i < argc) {
        a = argv[i++];

        if (*a == '-' && strcmp(a,"-") != 0/*not "-"*/) {
            do { a++; } while (*a == '-');

            if (!strcmp(a,"h") || !strcmp(a,"help")) {
                help();
                return 1;
            }
            else {
                fprintf(stderr,"Unknown switch %s\n",a);
                return 1;
            }
        }
        else {
            switch (nwac++) {
                case 0:
                    in_file = a;
                    break;
                case 1:
                    out_file = a;
                    break;
                default:
                    fprintf(stderr,"Unexpected arg %s\n",a);
                    return 1;
            }
        }
    }

    return 0;
}

void send_line(haxpp_linesink &ls,const string &name,const linecount_t line) {
    string msg = string("#line ") + to_string(line) + " \"" + name + "\"";
    ls.write(msg.c_str());
}

/* 's' should point to the first char of a word.
 * A word is a sequence of chars [a-zA-Z0-9_].
 * assumes s != NULL */
bool iswordchar(char c) {
    return isalnum(c) || c == '_';
}

void cstrskipwhitespace(char* &s) {
    while (*s == ' ' || *s == '\t') s++;
}

string cstrgetword(char* &s) {
    char *base = s;

    while (*s != 0) {
        if (iswordchar(*s)) {
            s++;
        }
        else {
            break;
        }
    }

    return string(base,(size_t)(s-base));
}

string cstrgetstringenclosed(char* &s,char delim,char delimend) {
    while (*s && *s != delim) s++;

    if (*s == delim) {
        char *base = ++s; /* skip delim and point to char after */
        while (*s && *s != delimend) s++;
        return string(base,(size_t)(s-base));
    }

    return string();
}

int main(int argc,char **argv) {
    if (parse_argv(argc,argv))
        return 1;

    in_lstk.push();
    if (in_file == "-")
        in_lstk.top().setsource(stdin);
    else
        in_lstk.top().setsource(in_file);

    if (!in_lstk.top().open()) {
        fprintf(stderr,"Unable to open infile, %s\n",strerror(errno));
        return 1;
    }

    if (out_file == "-")
        out_ls.setsink(stdout);
    else
        out_ls.setsink(out_file);

    if (!out_ls.open()) {
        fprintf(stderr,"Unable to open outfile, %s\n",strerror(errno));
        return 1;
    }
    send_line(out_ls,in_lstk.top().getsourcename(),1);

    while (!in_lstk.top().eof()) {
        char *line = in_lstk.top().readline();
        if (line == nullptr) {
            if (!in_lstk.top().error() && in_lstk.top().eof()) {
                in_lstk.pop();
                if (in_lstk.empty())
                    break;
                else
                    continue;
            }
            else {
                fprintf(stderr,"Problem reading. error=%u eof=%u errno=%s\n",in_lstk.top().error(),in_lstk.top().eof(),strerror(errno));
                return 1;
            }
        }

        /* look for preprocessor directives this code handles by itself */
        {
            char *s = line; cstrskipwhitespace(s);

            if (*s == '#') {
                s++; cstrskipwhitespace(s);

                const string what = cstrgetword(s); cstrskipwhitespace(s);

                if (what == "include") {
                    string path;

                    if (*s == '<')
                        path = cstrgetstringenclosed(s,'<','>');
                    else if (*s == '\"')
                        path = cstrgetstringenclosed(s,'\"','\"');
                    else {
                        fprintf(stderr,"#include statement with junk: %s\n",line);
                        return 1;
                    }

                    if (path.empty()) {
                        fprintf(stderr,"#include statement with no path\n");
                        return 1;
                    }

                    // TODO do something with path

                    continue; /* do not send to output */
                }
            }
        }

        if (!out_ls.write(line)) {
            fprintf(stderr,"Error writing output\n");
            return 1;
        }
    }

    if (!in_lstk.empty()) {
        if (in_lstk.top().error()) {
            fprintf(stderr,"An error occurred while parsing %s\n",in_lstk.top().getsourcename().c_str());
            return 1;
        }
    }

    if (out_ls.error()) {
        fprintf(stderr,"An error occurred while parsing %s\n",out_ls.getsinkname().c_str());
        return 1;
    }

    out_ls.close();
    in_lstk.clear();
    return 0;
}

<|endoftext|>


<commit_before>#include "util.h"
using namespace std;
namespace NP_MERGESORT {

	void printArray(A ** array, int size) {
		for (int index = 0; index < size; index++) {
			array[index]->print();
		}

		cout << "\n";
	}

	void merge(A ** array, int startIndex, int mid, int endIndex, int len) {
		A ** temp = new A * [len];

		int leftCursor = startIndex;
		int rightCursor = endIndex;
		int bookmark = mid + 1;
		int cursor = leftCursor;

		while (leftCursor <= mid && bookmark <= rightCursor) {
			if (*array[leftCursor] <= *array[bookmark])
				temp[cursor++] = array[leftCursor++];
			else
				temp[cursor++] = array[bookmark++];
		}

		while (leftCursor <= mid)
			temp[cursor++] = array[leftCursor++];

		while (bookmark <= rightCursor)
			temp[cursor++] = array[bookmark++];

		for (int index = startIndex; index <= endIndex; index++)
			array[index] = temp[index];

		cout << "After pass: ";
		printArray(array, len);
	}
	void mergesort(A ** array, int start, int end, int len) {
		if (start < end) {
			int mid = (start + end) / 2;
			mergesort(array, start, mid, len);
			mergesort(array, mid + 1, end, len);
			merge(array, start, mid, end, len);
		}
	}

}

using namespace NP_MERGESORT;

int main() {
	const int len = 7;
	A * array[len] = { &B(9), &B(4), &B(8), &B(3), &B(5), &B(2), &B(1) };
	cout << "Initial Array" << ": ";
	printArray(array, len);
	cout << "\n";
	mergesort(array, 0, len - 1, len);
	return 0;
}<commit_msg>move main in mergesort to hidden namespace<commit_after>#include "util.h"
using namespace std;
namespace NP_MERGESORT {

	void printArray(A ** array, int size) {
		for (int index = 0; index < size; index++) {
			array[index]->print();
		}

		cout << "\n";
	}

	void merge(A ** array, int startIndex, int mid, int endIndex, int len) {
		A ** temp = new A * [len];

		int leftCursor = startIndex;
		int rightCursor = endIndex;
		int bookmark = mid + 1;
		int cursor = leftCursor;

		while (leftCursor <= mid && bookmark <= rightCursor) {
			if (*array[leftCursor] <= *array[bookmark])
				temp[cursor++] = array[leftCursor++];
			else
				temp[cursor++] = array[bookmark++];
		}

		while (leftCursor <= mid)
			temp[cursor++] = array[leftCursor++];

		while (bookmark <= rightCursor)
			temp[cursor++] = array[bookmark++];

		for (int index = startIndex; index <= endIndex; index++)
			array[index] = temp[index];

		cout << "After pass: ";
		printArray(array, len);
	}
	void mergesort(A ** array, int start, int end, int len) {
		if (start < end) {
			int mid = (start + end) / 2;
			mergesort(array, start, mid, len);
			mergesort(array, mid + 1, end, len);
			merge(array, start, mid, end, len);
		}
	}

// }
	int main() {
		const int len = 7;
		A * array[len] = { &B(9), &B(4), &B(8), &B(3), &B(5), &B(2), &B(1) };
		cout << "Initial Array" << ": ";
		printArray(array, len);
		cout << "\n";
		mergesort(array, 0, len - 1, len);
		return 0;
	}

}
<|endoftext|>


<commit_before>/*============================================================================
This source file is an extension to the SoftFloat IEC/IEEE Floating-point
Arithmetic Package, Release 2b, written for Bochs (x86 achitecture simulator)
floating point emulation.

THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort has
been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.

Derivative works are acceptable, even for commercial purposes, so long as
(1) the source code for the derivative work includes prominent notice that
the work is derivative, and (2) the source code includes prominent notice with
these four paragraphs for those parts of this code that are retained.
=============================================================================*/

/*============================================================================
 * Written for Bochs (x86 achitecture simulator) by
 *            Stanislav Shwartsman [sshwarts at sourceforge net]
 * ==========================================================================*/

#include "softfloatx80.h"
#include "softfloat-round-pack.h"
#include "softfloat-macros.h"

/*----------------------------------------------------------------------------
| Returns the result of converting the extended double-precision floating-
| point value `a' to the 16-bit two's complement integer format.  The
| conversion is performed according to the IEC/IEEE Standard for Binary
| Floating-Point Arithmetic - which means in particular that the conversion
| is rounded according to the current rounding mode. If `a' is a NaN or the
| conversion overflows, the integer indefinite value is returned.
*----------------------------------------------------------------------------*/

Bit16s floatx80_to_int16(floatx80 a, float_status_t &status)
{
   if (floatx80_is_unsupported(a))
   {
        float_raise(status, float_flag_invalid);
        return int16_indefinite;
   }

   Bit32s v32 = floatx80_to_int32(a, status);

   if ((v32 > 32767) || (v32 < -32768)) {
        status.float_exception_flags = float_flag_invalid; // throw way other flags
        return int16_indefinite;
   }

   return (Bit16s) v32;
}

/*----------------------------------------------------------------------------
| Returns the result of converting the extended double-precision floating-
| point value `a' to the 16-bit two's complement integer format.  The
| conversion is performed according to the IEC/IEEE Standard for Binary
| Floating-Point Arithmetic, except that the conversion is always rounded
| toward zero.  If `a' is a NaN or the conversion overflows, the integer
| indefinite value is returned.
*----------------------------------------------------------------------------*/

Bit16s floatx80_to_int16_round_to_zero(floatx80 a, float_status_t &status)
{
   if (floatx80_is_unsupported(a))
   {
        float_raise(status, float_flag_invalid);
        return int16_indefinite;
   }

   Bit32s v32 = floatx80_to_int32_round_to_zero(a, status);

   if ((v32 > 32767) || (v32 < -32768)) {
        status.float_exception_flags = float_flag_invalid; // throw way other flags
        return int16_indefinite;
   }

   return (Bit16s) v32;
}

/*----------------------------------------------------------------------------
| Separate the source extended double-precision floating point value `a'
| into its exponent and significand, store the significant back to the
| 'a' and return the exponent. The operation performed is a superset of
| the IEC/IEEE recommended logb(x) function.
*----------------------------------------------------------------------------*/

floatx80 floatx80_extract(floatx80 &a, float_status_t &status)
{
    Bit64u aSig = extractFloatx80Frac(a);
    Bit32s aExp = extractFloatx80Exp(a);
    int   aSign = extractFloatx80Sign(a);

    if (floatx80_is_unsupported(a))
    {
        float_raise(status, float_flag_invalid);
        a = floatx80_default_nan;
        return a;
    }

    if (aExp == 0x7FFF) {
        if ((Bit64u) (aSig<<1))
        {
            a = propagateFloatx80NaN(a, status);
            return a;
        }
        return packFloatx80(0, 0x7FFF, BX_CONST64(0x8000000000000000));
    }
    if (aExp == 0)
    {
        if (aSig == 0) {
            float_raise(status, float_flag_divbyzero);
            a = packFloatx80(aSign, 0, 0);
            return packFloatx80(1, 0x7FFF, BX_CONST64(0x8000000000000000));
        }
        float_raise(status, float_flag_denormal);
        normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
    }

    a.exp = (aSign << 15) + 0x3FFF;
    a.fraction = aSig;
    return int32_to_floatx80(aExp - 0x3FFF);
}

/*----------------------------------------------------------------------------
| Scales extended double-precision floating-point value in operand `a' by
| value `b'. The function truncates the value in the second operand 'b' to
| an integral value and adds that value to the exponent of the operand 'a'.
| The operation performed according to the IEC/IEEE Standard for Binary
| Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/

floatx80 floatx80_scale(floatx80 a, floatx80 b, float_status_t &status)
{
    Bit32s aExp, bExp;
    Bit64u aSig, bSig;

    // handle unsupported extended double-precision floating encodings
    if (floatx80_is_unsupported(a) || floatx80_is_unsupported(b))
    {
        float_raise(status, float_flag_invalid);
        return floatx80_default_nan;
    }

    aSig = extractFloatx80Frac(a);
    aExp = extractFloatx80Exp(a);
    int aSign = extractFloatx80Sign(a);
    bSig = extractFloatx80Frac(b);
    bExp = extractFloatx80Exp(b);
    int bSign = extractFloatx80Sign(b);

    if (aExp == 0x7FFF) {
        if ((Bit64u) (aSig<<1) || ((bExp == 0x7FFF) && (Bit64u) (bSig<<1)))
        {
            return propagateFloatx80NaN(a, b, status);
        }
        if ((bExp == 0x7FFF) && bSign) {
            float_raise(status, float_flag_invalid);
            return floatx80_default_nan;
        }
        if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal);
        return a;
    }
    if (bExp == 0x7FFF) {
        if ((Bit64u) (bSig<<1)) return propagateFloatx80NaN(a, b, status);
        if ((aExp | aSig) == 0) {
            if (! bSign) {
                float_raise(status, float_flag_invalid);
                return floatx80_default_nan;
            }
            return a;
        }
        if (aSig && (aExp == 0)) float_raise(status, float_flag_denormal);
        if (bSign) return packFloatx80(aSign, 0, 0);
        return packFloatx80(aSign, 0x7FFF, BX_CONST64(0x8000000000000000));
    }
    if (aExp == 0) {
        if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal);
        if (aSig == 0) return a;
        float_raise(status, float_flag_denormal);
        normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
    }
    if (bExp == 0) {
        if (bSig == 0) return a;
        float_raise(status, float_flag_denormal);
        normalizeFloatx80Subnormal(bSig, &bExp, &bSig);
    }

    if (bExp > 0x400E) {
        /* generate appropriate overflow/underflow */
        return roundAndPackFloatx80(80, aSign,
                          bSign ? -0x3FFF : 0x7FFF, aSig, 0, status);
    }
    if (bExp < 0x3FFF) return a;

    int shiftCount = 0x403E - bExp;
    bSig >>= shiftCount;
    Bit32s scale = (Bit32s) bSig;
    if (bSign) scale = -scale; /* -32768..32767 */
    return
        roundAndPackFloatx80(80, aSign, aExp+scale, aSig, 0, status);
}

/*----------------------------------------------------------------------------
| Determine extended-precision floating-point number class.
*----------------------------------------------------------------------------*/

float_class_t floatx80_class(floatx80 a)
{
   Bit32s aExp = extractFloatx80Exp(a);
   Bit64u aSig = extractFloatx80Frac(a);

   if(aExp == 0) {
       if (aSig == 0)
           return float_zero;

       /* denormal or pseudo-denormal */
       return float_denormal;
   }

   /* valid numbers have the MS bit set */
   if (!(aSig & BX_CONST64(0x8000000000000000)))
       return float_NaN; /* report unsupported as NaNs */

   if(aExp == 0x7fff) {
       int aSign = extractFloatx80Sign(a);

       if (((Bit64u) (aSig<< 1)) == 0)
           return (aSign) ? float_negative_inf : float_positive_inf;

       return float_NaN;
   }

   return float_normalized;
}

/*----------------------------------------------------------------------------
| Compare  between  two extended precision  floating  point  numbers. Returns
| 'float_relation_equal'  if the operands are equal, 'float_relation_less' if
| the    value    'a'   is   less   than   the   corresponding   value   `b',
| 'float_relation_greater' if the value 'a' is greater than the corresponding
| value `b', or 'float_relation_unordered' otherwise.
*----------------------------------------------------------------------------*/

int floatx80_compare(floatx80 a, floatx80 b, float_status_t &status)
{
    float_class_t aClass = floatx80_class(a);
    float_class_t bClass = floatx80_class(b);

    if (aClass == float_NaN || bClass == float_NaN)
    {
        float_raise(status, float_flag_invalid);
        return float_relation_unordered;
    }

    if (aClass == float_denormal || bClass == float_denormal)
    {
        float_raise(status, float_flag_denormal);
    }

    int aSign = extractFloatx80Sign(a);
    int bSign = extractFloatx80Sign(b);

    if (aClass == float_zero) {
        if (bClass == float_zero) return float_relation_equal;
        return bSign ? float_relation_greater : float_relation_less;
    }

    if (bClass == float_zero || aSign != bSign) {
        return aSign ? float_relation_less : float_relation_greater;
    }

    Bit64u aSig = extractFloatx80Frac(a);
    Bit32s aExp = extractFloatx80Exp(a);
    Bit64u bSig = extractFloatx80Frac(b);
    Bit32s bExp = extractFloatx80Exp(b);

    if (aClass == float_denormal)
        normalizeFloatx80Subnormal(aSig, &aExp, &aSig);

    if (bClass == float_denormal)
        normalizeFloatx80Subnormal(bSig, &bExp, &bSig);

    if (aExp == bExp && aSig == bSig)
        return float_relation_equal;

    int less_than =
        aSign ? ((bExp < aExp) || ((bExp == aExp) && (bSig < aSig)))
              : ((aExp < bExp) || ((aExp == bExp) && (aSig < bSig)));

    if (less_than) return float_relation_less;
    return float_relation_greater;
}

/*----------------------------------------------------------------------------
| Compare  between  two extended precision  floating  point  numbers. Returns
| 'float_relation_equal'  if the operands are equal, 'float_relation_less' if
| the    value    'a'   is   less   than   the   corresponding   value   `b',
| 'float_relation_greater' if the value 'a' is greater than the corresponding
| value `b', or 'float_relation_unordered' otherwise. Quiet NaNs do not cause
| an exception.
*----------------------------------------------------------------------------*/

int floatx80_compare_quiet(floatx80 a, floatx80 b, float_status_t &status)
{
    float_class_t aClass = floatx80_class(a);
    float_class_t bClass = floatx80_class(b);

    if (aClass == float_NaN || bClass == float_NaN)
    {
        if (floatx80_is_unsupported(a) || floatx80_is_unsupported(b))
            float_raise(status, float_flag_invalid);

        if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
            float_raise(status, float_flag_invalid);

        return float_relation_unordered;
    }

    if (aClass == float_denormal || bClass == float_denormal)
    {
        float_raise(status, float_flag_denormal);
    }

    int aSign = extractFloatx80Sign(a);
    int bSign = extractFloatx80Sign(b);

    if (aClass == float_zero) {
        if (bClass == float_zero) return float_relation_equal;
        return bSign ? float_relation_greater : float_relation_less;
    }

    if (bClass == float_zero || aSign != bSign) {
        return aSign ? float_relation_less : float_relation_greater;
    }

    Bit64u aSig = extractFloatx80Frac(a);
    Bit32s aExp = extractFloatx80Exp(a);
    Bit64u bSig = extractFloatx80Frac(b);
    Bit32s bExp = extractFloatx80Exp(b);

    if (aClass == float_denormal)
        normalizeFloatx80Subnormal(aSig, &aExp, &aSig);

    if (bClass == float_denormal)
        normalizeFloatx80Subnormal(bSig, &bExp, &bSig);

    if (aExp == bExp && aSig == bSig)
        return float_relation_equal;

    int less_than =
        aSign ? ((bExp < aExp) || ((bExp == aExp) && (bSig < aSig)))
              : ((aExp < bExp) || ((aExp == bExp) && (aSig < bSig)));

    if (less_than) return float_relation_less;
    return float_relation_greater;
}
<commit_msg>fscale fix<commit_after>/*============================================================================
This source file is an extension to the SoftFloat IEC/IEEE Floating-point
Arithmetic Package, Release 2b, written for Bochs (x86 achitecture simulator)
floating point emulation.

THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort has
been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.

Derivative works are acceptable, even for commercial purposes, so long as
(1) the source code for the derivative work includes prominent notice that
the work is derivative, and (2) the source code includes prominent notice with
these four paragraphs for those parts of this code that are retained.
=============================================================================*/

/*============================================================================
 * Written for Bochs (x86 achitecture simulator) by
 *            Stanislav Shwartsman [sshwarts at sourceforge net]
 * ==========================================================================*/

#include "softfloatx80.h"
#include "softfloat-round-pack.h"
#include "softfloat-macros.h"

/*----------------------------------------------------------------------------
| Returns the result of converting the extended double-precision floating-
| point value `a' to the 16-bit two's complement integer format.  The
| conversion is performed according to the IEC/IEEE Standard for Binary
| Floating-Point Arithmetic - which means in particular that the conversion
| is rounded according to the current rounding mode. If `a' is a NaN or the
| conversion overflows, the integer indefinite value is returned.
*----------------------------------------------------------------------------*/

Bit16s floatx80_to_int16(floatx80 a, float_status_t &status)
{
   if (floatx80_is_unsupported(a))
   {
        float_raise(status, float_flag_invalid);
        return int16_indefinite;
   }

   Bit32s v32 = floatx80_to_int32(a, status);

   if ((v32 > 32767) || (v32 < -32768)) {
        status.float_exception_flags = float_flag_invalid; // throw way other flags
        return int16_indefinite;
   }

   return (Bit16s) v32;
}

/*----------------------------------------------------------------------------
| Returns the result of converting the extended double-precision floating-
| point value `a' to the 16-bit two's complement integer format.  The
| conversion is performed according to the IEC/IEEE Standard for Binary
| Floating-Point Arithmetic, except that the conversion is always rounded
| toward zero.  If `a' is a NaN or the conversion overflows, the integer
| indefinite value is returned.
*----------------------------------------------------------------------------*/

Bit16s floatx80_to_int16_round_to_zero(floatx80 a, float_status_t &status)
{
   if (floatx80_is_unsupported(a))
   {
        float_raise(status, float_flag_invalid);
        return int16_indefinite;
   }

   Bit32s v32 = floatx80_to_int32_round_to_zero(a, status);

   if ((v32 > 32767) || (v32 < -32768)) {
        status.float_exception_flags = float_flag_invalid; // throw way other flags
        return int16_indefinite;
   }

   return (Bit16s) v32;
}

/*----------------------------------------------------------------------------
| Separate the source extended double-precision floating point value `a'
| into its exponent and significand, store the significant back to the
| 'a' and return the exponent. The operation performed is a superset of
| the IEC/IEEE recommended logb(x) function.
*----------------------------------------------------------------------------*/

floatx80 floatx80_extract(floatx80 &a, float_status_t &status)
{
    Bit64u aSig = extractFloatx80Frac(a);
    Bit32s aExp = extractFloatx80Exp(a);
    int   aSign = extractFloatx80Sign(a);

    if (floatx80_is_unsupported(a))
    {
        float_raise(status, float_flag_invalid);
        a = floatx80_default_nan;
        return a;
    }

    if (aExp == 0x7FFF) {
        if ((Bit64u) (aSig<<1))
        {
            a = propagateFloatx80NaN(a, status);
            return a;
        }
        return packFloatx80(0, 0x7FFF, BX_CONST64(0x8000000000000000));
    }
    if (aExp == 0)
    {
        if (aSig == 0) {
            float_raise(status, float_flag_divbyzero);
            a = packFloatx80(aSign, 0, 0);
            return packFloatx80(1, 0x7FFF, BX_CONST64(0x8000000000000000));
        }
        float_raise(status, float_flag_denormal);
        normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
    }

    a.exp = (aSign << 15) + 0x3FFF;
    a.fraction = aSig;
    return int32_to_floatx80(aExp - 0x3FFF);
}

/*----------------------------------------------------------------------------
| Scales extended double-precision floating-point value in operand `a' by
| value `b'. The function truncates the value in the second operand 'b' to
| an integral value and adds that value to the exponent of the operand 'a'.
| The operation performed according to the IEC/IEEE Standard for Binary
| Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/

floatx80 floatx80_scale(floatx80 a, floatx80 b, float_status_t &status)
{
    Bit32s aExp, bExp;
    Bit64u aSig, bSig;

    // handle unsupported extended double-precision floating encodings
    if (floatx80_is_unsupported(a) || floatx80_is_unsupported(b))
    {
        float_raise(status, float_flag_invalid);
        return floatx80_default_nan;
    }

    aSig = extractFloatx80Frac(a);
    aExp = extractFloatx80Exp(a);
    int aSign = extractFloatx80Sign(a);
    bSig = extractFloatx80Frac(b);
    bExp = extractFloatx80Exp(b);
    int bSign = extractFloatx80Sign(b);

    if (aExp == 0x7FFF) {
        if ((Bit64u) (aSig<<1) || ((bExp == 0x7FFF) && (Bit64u) (bSig<<1)))
        {
            return propagateFloatx80NaN(a, b, status);
        }
        if ((bExp == 0x7FFF) && bSign) {
            float_raise(status, float_flag_invalid);
            return floatx80_default_nan;
        }
        if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal);
        return a;
    }
    if (bExp == 0x7FFF) {
        if ((Bit64u) (bSig<<1)) return propagateFloatx80NaN(a, b, status);
        if ((aExp | aSig) == 0) {
            if (! bSign) {
                float_raise(status, float_flag_invalid);
                return floatx80_default_nan;
            }
            return a;
        }
        if (aSig && (aExp == 0)) float_raise(status, float_flag_denormal);
        if (bSign) return packFloatx80(aSign, 0, 0);
        return packFloatx80(aSign, 0x7FFF, BX_CONST64(0x8000000000000000));
    }
    if (aExp == 0) {
        if (bSig && (bExp == 0)) float_raise(status, float_flag_denormal);
        if (aSig == 0) return a;
        float_raise(status, float_flag_denormal);
        normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
        if (bExp < 0x3FFF)
            return normalizeRoundAndPackFloatx80(80, aSign, aExp, aSig, 0, status);
    }
    if (bExp == 0) {
        if (bSig == 0) return a;
        float_raise(status, float_flag_denormal);
        normalizeFloatx80Subnormal(bSig, &bExp, &bSig);
    }

    if (bExp > 0x400E) {
        /* generate appropriate overflow/underflow */
        return roundAndPackFloatx80(80, aSign,
                          bSign ? -0x3FFF : 0x7FFF, aSig, 0, status);
    }

    if (bExp < 0x3FFF) return a;

    int shiftCount = 0x403E - bExp;
    bSig >>= shiftCount;
    Bit32s scale = (Bit32s) bSig;
    if (bSign) scale = -scale; /* -32768..32767 */
    return
        roundAndPackFloatx80(80, aSign, aExp+scale, aSig, 0, status);
}

/*----------------------------------------------------------------------------
| Determine extended-precision floating-point number class.
*----------------------------------------------------------------------------*/

float_class_t floatx80_class(floatx80 a)
{
   Bit32s aExp = extractFloatx80Exp(a);
   Bit64u aSig = extractFloatx80Frac(a);

   if(aExp == 0) {
       if (aSig == 0)
           return float_zero;

       /* denormal or pseudo-denormal */
       return float_denormal;
   }

   /* valid numbers have the MS bit set */
   if (!(aSig & BX_CONST64(0x8000000000000000)))
       return float_NaN; /* report unsupported as NaNs */

   if(aExp == 0x7fff) {
       int aSign = extractFloatx80Sign(a);

       if (((Bit64u) (aSig<< 1)) == 0)
           return (aSign) ? float_negative_inf : float_positive_inf;

       return float_NaN;
   }

   return float_normalized;
}

/*----------------------------------------------------------------------------
| Compare  between  two extended precision  floating  point  numbers. Returns
| 'float_relation_equal'  if the operands are equal, 'float_relation_less' if
| the    value    'a'   is   less   than   the   corresponding   value   `b',
| 'float_relation_greater' if the value 'a' is greater than the corresponding
| value `b', or 'float_relation_unordered' otherwise.
*----------------------------------------------------------------------------*/

int floatx80_compare(floatx80 a, floatx80 b, float_status_t &status)
{
    float_class_t aClass = floatx80_class(a);
    float_class_t bClass = floatx80_class(b);

    if (aClass == float_NaN || bClass == float_NaN)
    {
        float_raise(status, float_flag_invalid);
        return float_relation_unordered;
    }

    if (aClass == float_denormal || bClass == float_denormal)
    {
        float_raise(status, float_flag_denormal);
    }

    int aSign = extractFloatx80Sign(a);
    int bSign = extractFloatx80Sign(b);

    if (aClass == float_zero) {
        if (bClass == float_zero) return float_relation_equal;
        return bSign ? float_relation_greater : float_relation_less;
    }

    if (bClass == float_zero || aSign != bSign) {
        return aSign ? float_relation_less : float_relation_greater;
    }

    Bit64u aSig = extractFloatx80Frac(a);
    Bit32s aExp = extractFloatx80Exp(a);
    Bit64u bSig = extractFloatx80Frac(b);
    Bit32s bExp = extractFloatx80Exp(b);

    if (aClass == float_denormal)
        normalizeFloatx80Subnormal(aSig, &aExp, &aSig);

    if (bClass == float_denormal)
        normalizeFloatx80Subnormal(bSig, &bExp, &bSig);

    if (aExp == bExp && aSig == bSig)
        return float_relation_equal;

    int less_than =
        aSign ? ((bExp < aExp) || ((bExp == aExp) && (bSig < aSig)))
              : ((aExp < bExp) || ((aExp == bExp) && (aSig < bSig)));

    if (less_than) return float_relation_less;
    return float_relation_greater;
}

/*----------------------------------------------------------------------------
| Compare  between  two extended precision  floating  point  numbers. Returns
| 'float_relation_equal'  if the operands are equal, 'float_relation_less' if
| the    value    'a'   is   less   than   the   corresponding   value   `b',
| 'float_relation_greater' if the value 'a' is greater than the corresponding
| value `b', or 'float_relation_unordered' otherwise. Quiet NaNs do not cause
| an exception.
*----------------------------------------------------------------------------*/

int floatx80_compare_quiet(floatx80 a, floatx80 b, float_status_t &status)
{
    float_class_t aClass = floatx80_class(a);
    float_class_t bClass = floatx80_class(b);

    if (aClass == float_NaN || bClass == float_NaN)
    {
        if (floatx80_is_unsupported(a) || floatx80_is_unsupported(b))
            float_raise(status, float_flag_invalid);

        if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b))
            float_raise(status, float_flag_invalid);

        return float_relation_unordered;
    }

    if (aClass == float_denormal || bClass == float_denormal)
    {
        float_raise(status, float_flag_denormal);
    }

    int aSign = extractFloatx80Sign(a);
    int bSign = extractFloatx80Sign(b);

    if (aClass == float_zero) {
        if (bClass == float_zero) return float_relation_equal;
        return bSign ? float_relation_greater : float_relation_less;
    }

    if (bClass == float_zero || aSign != bSign) {
        return aSign ? float_relation_less : float_relation_greater;
    }

    Bit64u aSig = extractFloatx80Frac(a);
    Bit32s aExp = extractFloatx80Exp(a);
    Bit64u bSig = extractFloatx80Frac(b);
    Bit32s bExp = extractFloatx80Exp(b);

    if (aClass == float_denormal)
        normalizeFloatx80Subnormal(aSig, &aExp, &aSig);

    if (bClass == float_denormal)
        normalizeFloatx80Subnormal(bSig, &bExp, &bSig);

    if (aExp == bExp && aSig == bSig)
        return float_relation_equal;

    int less_than =
        aSign ? ((bExp < aExp) || ((bExp == aExp) && (bSig < aSig)))
              : ((aExp < bExp) || ((aExp == bExp) && (aSig < bSig)));

    if (less_than) return float_relation_less;
    return float_relation_greater;
}
<|endoftext|>