<commit_before>////////////////////////////////////////////////////////////////////////////////
/// @brief handler factory
///
/// @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 Dr. Frank Celler
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
/// @author Copyright 2009-2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////

#include "HttpHandlerFactory.h"

#include "Basics/StringUtils.h"
#include "Basics/logging.h"
#include "Basics/tri-strings.h"
#include "HttpServer/HttpHandler.h"
#include "Rest/HttpRequest.h"
#include "Rest/SslInterface.h"

using namespace triagens::basics;
using namespace triagens::rest;
using namespace std;

// -----------------------------------------------------------------------------
// --SECTION--                                                 private variables
// -----------------------------------------------------------------------------

namespace {
  sig_atomic_t MaintenanceMode = 0;
}

// -----------------------------------------------------------------------------
// --SECTION--                                                MaintenanceHandler
// -----------------------------------------------------------------------------

namespace {
  class MaintenanceHandler : public HttpHandler {
    public:
      MaintenanceHandler (HttpRequest* request)
        : HttpHandler(request) {
      };

      bool isDirect () const override {
        return true;
      };

      status_t execute () override {
        _response = createResponse(HttpResponse::SERVICE_UNAVAILABLE);

        return status_t(HANDLER_DONE);
      };

      void handleError (const Exception& error) {
        _response = createResponse(HttpResponse::SERVICE_UNAVAILABLE);
      };
  };
}

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

////////////////////////////////////////////////////////////////////////////////
/// @brief constructs a new handler factory
////////////////////////////////////////////////////////////////////////////////

HttpHandlerFactory::HttpHandlerFactory (std::string const& authenticationRealm,
                                        int32_t minCompatibility,
                                        bool allowMethodOverride,
                                        context_fptr setContext,
                                        void* setContextData)
  : _authenticationRealm(authenticationRealm),
    _minCompatibility(minCompatibility),
    _allowMethodOverride(allowMethodOverride),
    _setContext(setContext),
    _setContextData(setContextData),
    _notFound(0) {
}

////////////////////////////////////////////////////////////////////////////////
/// @brief clones a handler factory
////////////////////////////////////////////////////////////////////////////////

HttpHandlerFactory::HttpHandlerFactory (HttpHandlerFactory const& that)
  : _authenticationRealm(that._authenticationRealm),
    _minCompatibility(that._minCompatibility),
    _allowMethodOverride(that._allowMethodOverride),
    _setContext(that._setContext),
    _setContextData(that._setContextData),
    _constructors(that._constructors),
    _datas(that._datas),
    _prefixes(that._prefixes),
    _notFound(that._notFound) {
}

////////////////////////////////////////////////////////////////////////////////
/// @brief copies a handler factory
////////////////////////////////////////////////////////////////////////////////

HttpHandlerFactory& HttpHandlerFactory::operator= (HttpHandlerFactory const& that) {
  if (this != &that) {
    _authenticationRealm = that._authenticationRealm;
    _minCompatibility = that._minCompatibility;
    _allowMethodOverride = that._allowMethodOverride;
    _setContext = that._setContext;
    _setContextData = that._setContextData;
    _constructors = that._constructors;
    _datas = that._datas;
    _prefixes = that._prefixes;
    _notFound = that._notFound;
  }

  return *this;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief destructs a handler factory
////////////////////////////////////////////////////////////////////////////////

HttpHandlerFactory::~HttpHandlerFactory () {
}

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

////////////////////////////////////////////////////////////////////////////////
/// @brief sets maintenance mode
////////////////////////////////////////////////////////////////////////////////

void HttpHandlerFactory::setMaintenance (bool value) {
  MaintenanceMode = value ? 1 : 0;
}

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

////////////////////////////////////////////////////////////////////////////////
/// @brief returns header and body size restrictions
////////////////////////////////////////////////////////////////////////////////

HttpHandlerFactory::size_restriction_t HttpHandlerFactory::sizeRestrictions () const {
  size_restriction_t restrictions;

  restrictions.maximalHeaderSize = 1 * 1024 * 1024;  // 1 MByte
  restrictions.maximalBodySize = 512 * 1024 * 1024;  // 512 MByte
  restrictions.maximalPipelineSize = 2 * restrictions.maximalBodySize;

  return restrictions;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief authenticates a new request
///
/// wrapper method that will consider disabled authentication etc.
////////////////////////////////////////////////////////////////////////////////

HttpResponse::HttpResponseCode HttpHandlerFactory::authenticateRequest (HttpRequest* request) {
  auto context = request->getRequestContext();

  if (context == nullptr) {
    if (! setRequestContext(request)) {
      return HttpResponse::NOT_FOUND;
    }

    context = request->getRequestContext();
  }

  TRI_ASSERT(context != nullptr);

  return context->authenticate();
}

////////////////////////////////////////////////////////////////////////////////
/// @brief set request context, wrapper method
////////////////////////////////////////////////////////////////////////////////

bool HttpHandlerFactory::setRequestContext (HttpRequest* request) {
  return _setContext(request, _setContextData);
}

////////////////////////////////////////////////////////////////////////////////
/// @brief returns the authentication realm
////////////////////////////////////////////////////////////////////////////////

string HttpHandlerFactory::authenticationRealm (HttpRequest* request) const {
  auto context = request->getRequestContext();

  if (context != nullptr) {
    auto realm = context->getRealm();

    if (realm != nullptr) {
      return _authenticationRealm + "/" + std::string(realm);
    }
  }
  return _authenticationRealm;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief creates a new request
////////////////////////////////////////////////////////////////////////////////

HttpRequest* HttpHandlerFactory::createRequest (ConnectionInfo const& info,
                                                char const* ptr,
                                                size_t length) {
  HttpRequest* request = new HttpRequest(info, ptr, length, _minCompatibility, _allowMethodOverride);

  if (request != nullptr) {
    setRequestContext(request);
  }

  return request;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief creates a new handler
////////////////////////////////////////////////////////////////////////////////

HttpHandler* HttpHandlerFactory::createHandler (HttpRequest* request) {
  if (MaintenanceMode) {
    return new MaintenanceHandler(request);
  }

  unordered_map<string, create_fptr> const& ii = _constructors;
  string path = request->requestPath();
  auto i = ii.find(path);
  void* data = nullptr;

  // no direct match, check prefix matches
  if (i == ii.end()) {
    LOG_TRACE("no direct handler found, trying prefixes");

    // find longest match
    string prefix;
    vector<string> const& jj = _prefixes;
    const size_t pathLength = path.size();

    for (vector<string>::const_iterator j = jj.begin();  j != jj.end();  ++j) {
      string const& p = *j;
      const size_t pSize = p.size();

      if (path.compare(0, pSize, p) == 0) {
        if (pSize < pathLength && path[pSize] == '/') {
          if (prefix.size() < pSize) {
            prefix = p;
          }
        }
      }
    }

    if (prefix.empty()) {
      LOG_TRACE("no prefix handler found, trying catch all");

      i = ii.find("/");
      if (i != ii.end()) {
        LOG_TRACE("found catch all handler '/'");

        size_t l = 1;
        size_t n = path.find_first_of('/', l);

        while (n != string::npos) {
          request->addSuffix(path.substr(l, n - l).c_str());
          l = n + 1;
          n = path.find_first_of('/', l);
        }

        if (l < path.size()) {
          request->addSuffix(path.substr(l).c_str());
        }

        path = "/";
        request->setPrefix(path.c_str());
      }
    }

    else {
      LOG_TRACE("found prefix match '%s'", prefix.c_str());

      size_t l = prefix.size() + 1;
      size_t n = path.find_first_of('/', l);

      while (n != string::npos) {
        request->addSuffix(path.substr(l, n - l).c_str());
        l = n + 1;
        n = path.find_first_of('/', l);
      }

      if (l < path.size()) {
        request->addSuffix(path.substr(l).c_str());
      }

      path = prefix;
      request->setPrefix(path.c_str());

      i = ii.find(path);
    }
  }

  // no match
  if (i == ii.end()) {
    if (_notFound != nullptr) {
      HttpHandler* notFoundHandler = _notFound(request, data);
      notFoundHandler->setServer(this);

      return notFoundHandler;
    }
    else {
      LOG_TRACE("no not-found handler, giving up");
      return nullptr;
    }
  }

  // look up data
  unordered_map<string, void*> const& jj = _datas;
  auto j = jj.find(path);

  if (j != jj.end()) {
    data = j->second;
  }

  LOG_TRACE("found handler for path '%s'", path.c_str());
  HttpHandler* handler = i->second(request, data);

  handler->setServer(this);

  return handler;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief adds a path and constructor to the factory
////////////////////////////////////////////////////////////////////////////////

void HttpHandlerFactory::addHandler (string const& path, create_fptr func, void* data) {
  _constructors[path] = func;
  _datas[path] = data;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief adds a prefix path and constructor to the factory
////////////////////////////////////////////////////////////////////////////////

void HttpHandlerFactory::addPrefixHandler (string const& path, create_fptr func, void* data) {
  _constructors[path] = func;
  _datas[path] = data;
  _prefixes.push_back(path);
}

////////////////////////////////////////////////////////////////////////////////
/// @brief adds a path and constructor to the factory
////////////////////////////////////////////////////////////////////////////////

void HttpHandlerFactory::addNotFoundHandler (create_fptr func) {
  _notFound = func;
}

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

// Local Variables:
// mode: outline-minor
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
// End:
<commit_msg>slightly less string creation<commit_after>////////////////////////////////////////////////////////////////////////////////
/// @brief handler factory
///
/// @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 Dr. Frank Celler
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
/// @author Copyright 2009-2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////

#include "HttpHandlerFactory.h"

#include "Basics/StringUtils.h"
#include "Basics/logging.h"
#include "Basics/tri-strings.h"
#include "HttpServer/HttpHandler.h"
#include "Rest/HttpRequest.h"
#include "Rest/SslInterface.h"

using namespace triagens::basics;
using namespace triagens::rest;
using namespace std;

// -----------------------------------------------------------------------------
// --SECTION--                                                 private variables
// -----------------------------------------------------------------------------

namespace {
  sig_atomic_t MaintenanceMode = 0;
}

// -----------------------------------------------------------------------------
// --SECTION--                                                MaintenanceHandler
// -----------------------------------------------------------------------------

namespace {
  class MaintenanceHandler : public HttpHandler {
    public:
      MaintenanceHandler (HttpRequest* request)
        : HttpHandler(request) {
      };

      bool isDirect () const override {
        return true;
      };

      status_t execute () override {
        _response = createResponse(HttpResponse::SERVICE_UNAVAILABLE);

        return status_t(HANDLER_DONE);
      };

      void handleError (const Exception& error) {
        _response = createResponse(HttpResponse::SERVICE_UNAVAILABLE);
      };
  };
}

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

////////////////////////////////////////////////////////////////////////////////
/// @brief constructs a new handler factory
////////////////////////////////////////////////////////////////////////////////

HttpHandlerFactory::HttpHandlerFactory (std::string const& authenticationRealm,
                                        int32_t minCompatibility,
                                        bool allowMethodOverride,
                                        context_fptr setContext,
                                        void* setContextData)
  : _authenticationRealm(authenticationRealm),
    _minCompatibility(minCompatibility),
    _allowMethodOverride(allowMethodOverride),
    _setContext(setContext),
    _setContextData(setContextData),
    _notFound(nullptr) {
}

////////////////////////////////////////////////////////////////////////////////
/// @brief clones a handler factory
////////////////////////////////////////////////////////////////////////////////

HttpHandlerFactory::HttpHandlerFactory (HttpHandlerFactory const& that)
  : _authenticationRealm(that._authenticationRealm),
    _minCompatibility(that._minCompatibility),
    _allowMethodOverride(that._allowMethodOverride),
    _setContext(that._setContext),
    _setContextData(that._setContextData),
    _constructors(that._constructors),
    _datas(that._datas),
    _prefixes(that._prefixes),
    _notFound(that._notFound) {
}

////////////////////////////////////////////////////////////////////////////////
/// @brief copies a handler factory
////////////////////////////////////////////////////////////////////////////////

HttpHandlerFactory& HttpHandlerFactory::operator= (HttpHandlerFactory const& that) {
  if (this != &that) {
    _authenticationRealm = that._authenticationRealm;
    _minCompatibility = that._minCompatibility;
    _allowMethodOverride = that._allowMethodOverride;
    _setContext = that._setContext;
    _setContextData = that._setContextData;
    _constructors = that._constructors;
    _datas = that._datas;
    _prefixes = that._prefixes;
    _notFound = that._notFound;
  }

  return *this;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief destructs a handler factory
////////////////////////////////////////////////////////////////////////////////

HttpHandlerFactory::~HttpHandlerFactory () {
}

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

////////////////////////////////////////////////////////////////////////////////
/// @brief sets maintenance mode
////////////////////////////////////////////////////////////////////////////////

void HttpHandlerFactory::setMaintenance (bool value) {
  MaintenanceMode = value ? 1 : 0;
}

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

////////////////////////////////////////////////////////////////////////////////
/// @brief returns header and body size restrictions
////////////////////////////////////////////////////////////////////////////////

HttpHandlerFactory::size_restriction_t HttpHandlerFactory::sizeRestrictions () const {
  size_restriction_t restrictions;

  restrictions.maximalHeaderSize = 1 * 1024 * 1024;  // 1 MByte
  restrictions.maximalBodySize = 512 * 1024 * 1024;  // 512 MByte
  restrictions.maximalPipelineSize = 2 * restrictions.maximalBodySize;

  return restrictions;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief authenticates a new request
///
/// wrapper method that will consider disabled authentication etc.
////////////////////////////////////////////////////////////////////////////////

HttpResponse::HttpResponseCode HttpHandlerFactory::authenticateRequest (HttpRequest* request) {
  auto context = request->getRequestContext();

  if (context == nullptr) {
    if (! setRequestContext(request)) {
      return HttpResponse::NOT_FOUND;
    }

    context = request->getRequestContext();
  }

  TRI_ASSERT(context != nullptr);

  return context->authenticate();
}

////////////////////////////////////////////////////////////////////////////////
/// @brief set request context, wrapper method
////////////////////////////////////////////////////////////////////////////////

bool HttpHandlerFactory::setRequestContext (HttpRequest* request) {
  return _setContext(request, _setContextData);
}

////////////////////////////////////////////////////////////////////////////////
/// @brief returns the authentication realm
////////////////////////////////////////////////////////////////////////////////

string HttpHandlerFactory::authenticationRealm (HttpRequest* request) const {
  auto context = request->getRequestContext();

  if (context != nullptr) {
    auto realm = context->getRealm();

    if (realm != nullptr) {
      return _authenticationRealm + "/" + std::string(realm);
    }
  }
  return _authenticationRealm;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief creates a new request
////////////////////////////////////////////////////////////////////////////////

HttpRequest* HttpHandlerFactory::createRequest (ConnectionInfo const& info,
                                                char const* ptr,
                                                size_t length) {
  HttpRequest* request = new HttpRequest(info, ptr, length, _minCompatibility, _allowMethodOverride);

  if (request != nullptr) {
    setRequestContext(request);
  }

  return request;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief creates a new handler
////////////////////////////////////////////////////////////////////////////////

HttpHandler* HttpHandlerFactory::createHandler (HttpRequest* request) {
  if (MaintenanceMode) {
    return new MaintenanceHandler(request);
  }

  unordered_map<string, create_fptr> const& ii = _constructors;
  string path = request->requestPath();
  auto i = ii.find(path);
  void* data = nullptr;

  // no direct match, check prefix matches
  if (i == ii.end()) {
    LOG_TRACE("no direct handler found, trying prefixes");

    // find longest match
    string prefix;
    size_t const pathLength = path.size();

    for (auto const& p : _prefixes) {
      const size_t pSize = p.size();

      if (path.compare(0, pSize, p) == 0) {
        if (pSize < pathLength && path[pSize] == '/') {
          if (prefix.size() < pSize) {
            prefix = p;
          }
        }
      }
    }

    if (prefix.empty()) {
      LOG_TRACE("no prefix handler found, trying catch all");

      i = ii.find("/");
      if (i != ii.end()) {
        LOG_TRACE("found catch all handler '/'");

        size_t l = 1;
        size_t n = path.find_first_of('/', l);

        while (n != string::npos) {
          request->addSuffix(path.substr(l, n - l));
          l = n + 1;
          n = path.find_first_of('/', l);
        }

        if (l < path.size()) {
          request->addSuffix(path.substr(l));
        }

        path = "/";
        request->setPrefix(path.c_str());
      }
    }

    else {
      LOG_TRACE("found prefix match '%s'", prefix.c_str());

      size_t l = prefix.size() + 1;
      size_t n = path.find_first_of('/', l);

      while (n != string::npos) {
        request->addSuffix(path.substr(l, n - l));
        l = n + 1;
        n = path.find_first_of('/', l);
      }

      if (l < path.size()) {
        request->addSuffix(path.substr(l));
      }

      path = prefix;
      request->setPrefix(path.c_str());

      i = ii.find(path);
    }
  }

  // no match
  if (i == ii.end()) {
    if (_notFound != nullptr) {
      HttpHandler* notFoundHandler = _notFound(request, data);
      notFoundHandler->setServer(this);

      return notFoundHandler;
    }
    else {
      LOG_TRACE("no not-found handler, giving up");
      return nullptr;
    }
  }

  // look up data
  {
    auto const& it = _datas.find(path);

    if (it != _datas.end()) {
      data = (*it).second;
    }
  }

  LOG_TRACE("found handler for path '%s'", path.c_str());
  HttpHandler* handler = i->second(request, data);

  handler->setServer(this);

  return handler;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief adds a path and constructor to the factory
////////////////////////////////////////////////////////////////////////////////

void HttpHandlerFactory::addHandler (string const& path, create_fptr func, void* data) {
  _constructors[path] = func;
  _datas[path] = data;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief adds a prefix path and constructor to the factory
////////////////////////////////////////////////////////////////////////////////

void HttpHandlerFactory::addPrefixHandler (string const& path, create_fptr func, void* data) {
  _constructors[path] = func;
  _datas[path] = data;
  _prefixes.emplace_back(path);
}

////////////////////////////////////////////////////////////////////////////////
/// @brief adds a path and constructor to the factory
////////////////////////////////////////////////////////////////////////////////

void HttpHandlerFactory::addNotFoundHandler (create_fptr func) {
  _notFound = func;
}

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

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


<commit_before>//===-- SlowOperationInformer.cpp - Keep the user informed ----------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the SlowOperationInformer class for the LLVM debugger.
//
//===----------------------------------------------------------------------===//

#include "llvm/Support/SlowOperationInformer.h"
#include "llvm/Config/config.h"     // Get the signal handler return type
#include <iostream>
#include <sstream>
#include <signal.h>
#include <unistd.h>
#include <cassert>
using namespace llvm;

/// OperationCancelled - This flag is set by the SIGINT signal handler if the
/// user presses CTRL-C.
static volatile bool OperationCancelled;

/// ShouldShowStatus - This flag gets set if the operation takes a long time.
///
static volatile bool ShouldShowStatus;

/// NestedSOI - Sanity check.  SlowOperationInformers cannot be nested or run in
/// parallel.  This ensures that they never do.
static bool NestedSOI = false;

static RETSIGTYPE SigIntHandler(int Sig) {
  OperationCancelled = true;
  signal(SIGINT, SigIntHandler);
}

static RETSIGTYPE SigAlarmHandler(int Sig) {
  ShouldShowStatus = true;
}

static void (*OldSigIntHandler) (int);

SlowOperationInformer::SlowOperationInformer(const std::string &Name)
  : OperationName(Name), LastPrintAmount(0) {
  assert(!NestedSOI && "SlowerOperationInformer objects cannot be nested!");
  NestedSOI = true;

  OperationCancelled = 0;
  ShouldShowStatus = 0;

  signal(SIGALRM, SigAlarmHandler);
  OldSigIntHandler = signal(SIGINT, SigIntHandler);
  alarm(1);
}

SlowOperationInformer::~SlowOperationInformer() {
  NestedSOI = false;
  if (LastPrintAmount) {
    // If we have printed something, make _sure_ we print the 100% amount, and
    // also print a newline.
    std::cout << std::string(LastPrintAmount, '\b') << "Progress "
              << OperationName << ": 100%  \n";
  }

  alarm(0);
  signal(SIGALRM, SIG_DFL);
  signal(SIGINT, OldSigIntHandler);
}

/// progress - Clients should periodically call this method when they are in
/// an exception-safe state.  The Amount variable should indicate how far
/// along the operation is, given in 1/10ths of a percent (in other words,
/// Amount should range from 0 to 1000).
void SlowOperationInformer::progress(unsigned Amount) {
  if (OperationCancelled) {
    std::cout << "\n";
    LastPrintAmount = 0;
    throw "While " + OperationName + ", operation cancelled.";
  }

  // If we haven't spent enough time in this operation to warrant displaying the
  // progress bar, don't do so yet.
  if (!ShouldShowStatus)
    return;

  // Delete whatever we printed last time.
  std::string ToPrint = std::string(LastPrintAmount, '\b');

  std::ostringstream OS;
  OS << "Progress " << OperationName << ": " << Amount/10;
  if (unsigned Rem = Amount % 10)
    OS << "." << Rem << "%";
  else
    OS << "%  ";

  LastPrintAmount = OS.str().size();
  std::cout << ToPrint+OS.str() << std::flush;
}
<commit_msg>For PR351: Move the system dependent portion to lib/System/*/Alarm.inc. This makes the SlowOperationInformer platform independent.<commit_after>//===-- SlowOperationInformer.cpp - Keep the user informed ----------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the SlowOperationInformer class for the LLVM debugger.
//
//===----------------------------------------------------------------------===//

#include "llvm/Support/SlowOperationInformer.h"
#include "llvm/System/Alarm.h"
#include <iostream>
#include <sstream>
#include <cassert>
using namespace llvm;

SlowOperationInformer::SlowOperationInformer(const std::string &Name)
  : OperationName(Name), LastPrintAmount(0) {
  sys::SetupAlarm(1);
}

SlowOperationInformer::~SlowOperationInformer() {
  sys::TerminateAlarm();
  if (LastPrintAmount) {
    // If we have printed something, make _sure_ we print the 100% amount, and
    // also print a newline.
    std::cout << std::string(LastPrintAmount, '\b') << "Progress "
              << OperationName << ": 100%  \n";
  }
}

/// progress - Clients should periodically call this method when they are in
/// an exception-safe state.  The Amount variable should indicate how far
/// along the operation is, given in 1/10ths of a percent (in other words,
/// Amount should range from 0 to 1000).
void SlowOperationInformer::progress(unsigned Amount) {
  int status = sys::AlarmStatus();
  if (status == -1) {
    std::cout << "\n";
    LastPrintAmount = 0;
    throw "While " + OperationName + ", operation cancelled.";
  }

  // If we haven't spent enough time in this operation to warrant displaying the
  // progress bar, don't do so yet.
  if (status == 0)
    return;

  // Delete whatever we printed last time.
  std::string ToPrint = std::string(LastPrintAmount, '\b');

  std::ostringstream OS;
  OS << "Progress " << OperationName << ": " << Amount/10;
  if (unsigned Rem = Amount % 10)
    OS << "." << Rem << "%";
  else
    OS << "%  ";

  LastPrintAmount = OS.str().size();
  std::cout << ToPrint+OS.str() << std::flush;
}
<|endoftext|>


<commit_before>/**************************************************************************
**
** Copyright (C) 2011,2012,2013 BlackBerry Limited. All rights reserved.
**
** Contact: BlackBerry Limited (qt@blackberry.com)
** Contact: KDAB (info@kdab.com)
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include "blackberryconfiguration.h"
#include "blackberryqtversion.h"

#include "qnxutils.h"

#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/kitmanager.h>
#include <projectexplorer/kitinformation.h>
#include <projectexplorer/toolchainmanager.h>

#include <qtsupport/baseqtversion.h>
#include <qtsupport/qtversionmanager.h>
#include <qtsupport/qtkitinformation.h>

#include <qt4projectmanager/qmakekitinformation.h>

#include <debugger/debuggerkitinformation.h>

#include <QFileInfo>
#include <QDir>
#include <QMessageBox>

using namespace ProjectExplorer;
using namespace QtSupport;
using namespace Utils;

namespace Qnx {
namespace Internal {

BlackBerryConfiguration::BlackBerryConfiguration(const FileName &ndkEnvFile, bool isAutoDetected,
                                                 const QString &displayName)
{
    Q_ASSERT(!QFileInfo(ndkEnvFile.toString()).isDir());
    m_ndkEnvFile = ndkEnvFile;
    m_isAutoDetected = isAutoDetected;
    QString ndkPath = ndkEnvFile.parentDir().toString();
    m_displayName = displayName.isEmpty() ? ndkPath.split(QDir::separator()).last() : displayName;
    m_qnxEnv = QnxUtils::parseEnvironmentFile(m_ndkEnvFile.toString());

    QString ndkTarget = m_qnxEnv.value(QLatin1String("QNX_TARGET"));
    QString sep = QString::fromLatin1("%1qnx6").arg(QDir::separator());
    m_targetName = ndkTarget.split(sep).first().split(QDir::separator()).last();

    if (QDir(ndkTarget).exists())
        m_sysRoot = FileName::fromString(ndkTarget);

    QString qnxHost = m_qnxEnv.value(QLatin1String("QNX_HOST"));
    FileName qmake4Path = QnxUtils::executableWithExtension(FileName::fromString(qnxHost + QLatin1String("/usr/bin/qmake")));
    FileName qmake5Path = QnxUtils::executableWithExtension(FileName::fromString(qnxHost + QLatin1String("/usr/bin/qt5/qmake")));
    FileName gccPath = QnxUtils::executableWithExtension(FileName::fromString(qnxHost + QLatin1String("/usr/bin/qcc")));
    FileName deviceGdbPath = QnxUtils::executableWithExtension(FileName::fromString(qnxHost + QLatin1String("/usr/bin/ntoarm-gdb")));
    FileName simulatorGdbPath = QnxUtils::executableWithExtension(FileName::fromString(qnxHost + QLatin1String("/usr/bin/ntox86-gdb")));

    if (qmake4Path.toFileInfo().exists())
        m_qmake4BinaryFile = qmake4Path;

    if (qmake5Path.toFileInfo().exists())
        m_qmake5BinaryFile = qmake5Path;

    if (gccPath.toFileInfo().exists())
        m_gccCompiler = gccPath;

    if (deviceGdbPath.toFileInfo().exists())
        m_deviceDebugger = deviceGdbPath;

    if (simulatorGdbPath.toFileInfo().exists())
        m_simulatorDebugger = simulatorGdbPath;
}

QString BlackBerryConfiguration::ndkPath() const
{
    return m_ndkEnvFile.parentDir().toString();
}

QString BlackBerryConfiguration::displayName() const
{
    return m_displayName;
}

QString BlackBerryConfiguration::targetName() const
{
    return m_targetName;
}

bool BlackBerryConfiguration::isAutoDetected() const
{
    return m_isAutoDetected;
}

bool BlackBerryConfiguration::isActive() const
{
    return !findRegisteredQtVersions().isEmpty();
}

bool BlackBerryConfiguration::isValid() const
{
    return !((m_qmake4BinaryFile.isEmpty() && m_qmake5BinaryFile.isEmpty()) || m_gccCompiler.isEmpty()
            || m_deviceDebugger.isEmpty() || m_simulatorDebugger.isEmpty());
}

FileName BlackBerryConfiguration::ndkEnvFile() const
{
    return m_ndkEnvFile;
}

FileName BlackBerryConfiguration::qmake4BinaryFile() const
{
    return m_qmake4BinaryFile;
}

FileName BlackBerryConfiguration::qmake5BinaryFile() const
{
    return m_qmake5BinaryFile;
}

FileName BlackBerryConfiguration::gccCompiler() const
{
    return m_gccCompiler;
}

FileName BlackBerryConfiguration::deviceDebuger() const
{
    return m_deviceDebugger;
}

FileName BlackBerryConfiguration::simulatorDebuger() const
{
    return m_simulatorDebugger;
}

FileName BlackBerryConfiguration::sysRoot() const
{
    return m_sysRoot;
}

QMultiMap<QString, QString> BlackBerryConfiguration::qnxEnv() const
{
    return m_qnxEnv;
}

void BlackBerryConfiguration::createConfigurationPerQtVersion(
        const FileName &qmakePath, Qnx::QnxArchitecture arch)
{
    QnxAbstractQtVersion *version = createQtVersion(qmakePath, arch);
    ToolChain *toolChain = createGccToolChain(version);
    Kit *kit = createKit(version, toolChain);

    if (version && toolChain && kit) {
        // register
        QtVersionManager::addVersion(version);
        ToolChainManager::registerToolChain(toolChain);
        KitManager::registerKit(kit);
    }
}

QnxAbstractQtVersion *BlackBerryConfiguration::createQtVersion(
        const FileName &qmakePath, Qnx::QnxArchitecture arch)
{
    QnxAbstractQtVersion *version = new BlackBerryQtVersion(
            arch, qmakePath, true, QString(), m_ndkEnvFile.toString());
    version->setDisplayName(tr("Qt %1 for %2 %3 - %4").arg(
            version->qtVersionString(), version->platformDisplayName(),
            version->archString(), m_targetName));
    return version;
}

GccToolChain *BlackBerryConfiguration::createGccToolChain(QnxAbstractQtVersion *version)
{
    GccToolChain* toolChain = new GccToolChain(
            QLatin1String(ProjectExplorer::Constants::GCC_TOOLCHAIN_ID), ToolChain::AutoDetection);
    toolChain->setDisplayName(tr("QCC for Qt %1 for %2 %3 - %4").arg(
            version->qtVersionString(), version->platformDisplayName(),
            version->archString(), m_targetName));
    toolChain->setCompilerCommand(m_gccCompiler);
    QList<Abi> abis = version->qtAbis();
    if (!abis.isEmpty())
        toolChain->setTargetAbi(abis.first());
    return toolChain;
}

Kit *BlackBerryConfiguration::createKit(QnxAbstractQtVersion *version, ToolChain *toolChain)
{
    Kit *kit = new Kit;
    bool isSimulator = version->architecture() == X86;

    QtKitInformation::setQtVersion(kit, version);
    ToolChainKitInformation::setToolChain(kit, toolChain);

    Debugger::DebuggerItem debugger;
    debugger.setCommand(isSimulator ? m_simulatorDebugger : m_deviceDebugger);
    debugger.setEngineType(Debugger::GdbEngineType);
    debugger.setAutoDetected(true);
    debugger.setAbi(toolChain->targetAbi());
    debugger.setDisplayName(tr("Debugger for Qt %1 for %2 %3 - %4").arg(
            version->qtVersionString(), version->platformDisplayName(),
            version->archString(), m_targetName));
    Debugger::DebuggerKitInformation::setDebugger(kit, debugger);

    if (isSimulator)
        Qt4ProjectManager::QmakeKitInformation::setMkspec(
                 kit, FileName::fromString(QLatin1String("blackberry-x86-qcc")));

    DeviceTypeKitInformation::setDeviceTypeId(kit, Constants::QNX_BB_OS_TYPE);
    SysRootKitInformation::setSysRoot(kit, m_sysRoot);

    kit->setDisplayName(tr("%1 %2 - Qt %3 - %4").arg(
            version->platformDisplayName(), isSimulator ? tr("Simulator") : tr("Device"),
            version->qtVersionString(), m_targetName));
    kit->setIconPath(FileName::fromString(QLatin1String(Constants::QNX_BB_CATEGORY_ICON)));

    kit->setAutoDetected(true);
    kit->setMutable(DeviceKitInformation::id(), true);

    kit->setSticky(QtKitInformation::id(), true);
    kit->setSticky(ToolChainKitInformation::id(), true);
    kit->setSticky(DeviceTypeKitInformation::id(), true);
    kit->setSticky(SysRootKitInformation::id(), true);
    kit->setSticky(Debugger::DebuggerKitInformation::id(), true);
    kit->setSticky(Qt4ProjectManager::QmakeKitInformation::id(), true);

    return kit;
}

bool BlackBerryConfiguration::activate()
{
    if (!isValid()) {
        if (m_isAutoDetected)
            return false;

        QString errorMessage = tr("The following errors occurred while activating target: %1").arg(m_targetName);
        if (m_qmake4BinaryFile.isEmpty() && m_qmake5BinaryFile.isEmpty())
            errorMessage += QLatin1Char('\n') + tr("- No Qt version found.");

        if (m_gccCompiler.isEmpty())
            errorMessage += QLatin1Char('\n') + tr("- No GCC compiler found.");

        if (m_deviceDebugger.isEmpty())
            errorMessage += QLatin1Char('\n') + tr("- No GDB debugger found for BB10 Device.");

        if (!m_simulatorDebugger.isEmpty())
            errorMessage += QLatin1Char('\n') + tr("- No GDB debugger found for BB10 Simulator.");

        QMessageBox::warning(0, tr("Cannot Set up BB10 Configuration"),
                             errorMessage, QMessageBox::Ok);
        return false;
    }

    if (isActive())
        return true;

    deactivate(); // cleaning-up artifacts autodetected by old QtCreator versions

    if (!m_qmake4BinaryFile.isEmpty()) {
        createConfigurationPerQtVersion(m_qmake4BinaryFile, Qnx::ArmLeV7);
        createConfigurationPerQtVersion(m_qmake4BinaryFile, Qnx::X86);
    }

    if (!m_qmake5BinaryFile.isEmpty()) {
        createConfigurationPerQtVersion(m_qmake5BinaryFile, Qnx::ArmLeV7);
        createConfigurationPerQtVersion(m_qmake5BinaryFile, Qnx::X86);
    }

    return true;
}

QList<BaseQtVersion *> BlackBerryConfiguration::findRegisteredQtVersions() const
{
    QList<BaseQtVersion *> versions;
    foreach (BaseQtVersion *version, QtVersionManager::versions()) {
        if (version->type() == QLatin1String(Constants::QNX_BB_QT)) {
            QnxAbstractQtVersion *qnxVersion = dynamic_cast<QnxAbstractQtVersion *>(version);
            if (qnxVersion  &&  qnxVersion->isAutodetected()
                    && (qnxVersion->qmakeCommand() == qmake4BinaryFile()
                    || qnxVersion->qmakeCommand() == qmake5BinaryFile()))
                versions << qnxVersion;
        }
    }
    return versions;
}

void BlackBerryConfiguration::deactivate()
{
    QList<BaseQtVersion *> versions = findRegisteredQtVersions();
    QList<ToolChain *> toolChains;
    foreach (Kit *kit, KitManager::kits()) {
        if (kit->isAutoDetected()) {
            BaseQtVersion *version = QtKitInformation::qtVersion(kit);
            if (versions.contains(version)) {
                ToolChain *toolChain = ToolChainKitInformation::toolChain(kit);
                if (toolChain)
                    toolChains << toolChain;
                KitManager::deregisterKit(kit);
            }
        }
    }

    // unable to deregistering debuggers because of missing API

    foreach (ToolChain *toolChain, ToolChainManager::toolChains())
        if (toolChain->isAutoDetected()
                && (toolChains.contains(toolChain) || toolChain->compilerCommand() == m_gccCompiler))
            ToolChainManager::deregisterToolChain(toolChain);

    foreach (BaseQtVersion *version, versions)
        QtVersionManager::removeVersion(version);
}

} // namespace Internal
} // namespace Qnx
<commit_msg>QNX: Add explanatory Linguist comment about QCC being a compiler.<commit_after>/**************************************************************************
**
** Copyright (C) 2011,2012,2013 BlackBerry Limited. All rights reserved.
**
** Contact: BlackBerry Limited (qt@blackberry.com)
** Contact: KDAB (info@kdab.com)
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include "blackberryconfiguration.h"
#include "blackberryqtversion.h"

#include "qnxutils.h"

#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/kitmanager.h>
#include <projectexplorer/kitinformation.h>
#include <projectexplorer/toolchainmanager.h>

#include <qtsupport/baseqtversion.h>
#include <qtsupport/qtversionmanager.h>
#include <qtsupport/qtkitinformation.h>

#include <qt4projectmanager/qmakekitinformation.h>

#include <debugger/debuggerkitinformation.h>

#include <QFileInfo>
#include <QDir>
#include <QMessageBox>

using namespace ProjectExplorer;
using namespace QtSupport;
using namespace Utils;

namespace Qnx {
namespace Internal {

BlackBerryConfiguration::BlackBerryConfiguration(const FileName &ndkEnvFile, bool isAutoDetected,
                                                 const QString &displayName)
{
    Q_ASSERT(!QFileInfo(ndkEnvFile.toString()).isDir());
    m_ndkEnvFile = ndkEnvFile;
    m_isAutoDetected = isAutoDetected;
    QString ndkPath = ndkEnvFile.parentDir().toString();
    m_displayName = displayName.isEmpty() ? ndkPath.split(QDir::separator()).last() : displayName;
    m_qnxEnv = QnxUtils::parseEnvironmentFile(m_ndkEnvFile.toString());

    QString ndkTarget = m_qnxEnv.value(QLatin1String("QNX_TARGET"));
    QString sep = QString::fromLatin1("%1qnx6").arg(QDir::separator());
    m_targetName = ndkTarget.split(sep).first().split(QDir::separator()).last();

    if (QDir(ndkTarget).exists())
        m_sysRoot = FileName::fromString(ndkTarget);

    QString qnxHost = m_qnxEnv.value(QLatin1String("QNX_HOST"));
    FileName qmake4Path = QnxUtils::executableWithExtension(FileName::fromString(qnxHost + QLatin1String("/usr/bin/qmake")));
    FileName qmake5Path = QnxUtils::executableWithExtension(FileName::fromString(qnxHost + QLatin1String("/usr/bin/qt5/qmake")));
    FileName gccPath = QnxUtils::executableWithExtension(FileName::fromString(qnxHost + QLatin1String("/usr/bin/qcc")));
    FileName deviceGdbPath = QnxUtils::executableWithExtension(FileName::fromString(qnxHost + QLatin1String("/usr/bin/ntoarm-gdb")));
    FileName simulatorGdbPath = QnxUtils::executableWithExtension(FileName::fromString(qnxHost + QLatin1String("/usr/bin/ntox86-gdb")));

    if (qmake4Path.toFileInfo().exists())
        m_qmake4BinaryFile = qmake4Path;

    if (qmake5Path.toFileInfo().exists())
        m_qmake5BinaryFile = qmake5Path;

    if (gccPath.toFileInfo().exists())
        m_gccCompiler = gccPath;

    if (deviceGdbPath.toFileInfo().exists())
        m_deviceDebugger = deviceGdbPath;

    if (simulatorGdbPath.toFileInfo().exists())
        m_simulatorDebugger = simulatorGdbPath;
}

QString BlackBerryConfiguration::ndkPath() const
{
    return m_ndkEnvFile.parentDir().toString();
}

QString BlackBerryConfiguration::displayName() const
{
    return m_displayName;
}

QString BlackBerryConfiguration::targetName() const
{
    return m_targetName;
}

bool BlackBerryConfiguration::isAutoDetected() const
{
    return m_isAutoDetected;
}

bool BlackBerryConfiguration::isActive() const
{
    return !findRegisteredQtVersions().isEmpty();
}

bool BlackBerryConfiguration::isValid() const
{
    return !((m_qmake4BinaryFile.isEmpty() && m_qmake5BinaryFile.isEmpty()) || m_gccCompiler.isEmpty()
            || m_deviceDebugger.isEmpty() || m_simulatorDebugger.isEmpty());
}

FileName BlackBerryConfiguration::ndkEnvFile() const
{
    return m_ndkEnvFile;
}

FileName BlackBerryConfiguration::qmake4BinaryFile() const
{
    return m_qmake4BinaryFile;
}

FileName BlackBerryConfiguration::qmake5BinaryFile() const
{
    return m_qmake5BinaryFile;
}

FileName BlackBerryConfiguration::gccCompiler() const
{
    return m_gccCompiler;
}

FileName BlackBerryConfiguration::deviceDebuger() const
{
    return m_deviceDebugger;
}

FileName BlackBerryConfiguration::simulatorDebuger() const
{
    return m_simulatorDebugger;
}

FileName BlackBerryConfiguration::sysRoot() const
{
    return m_sysRoot;
}

QMultiMap<QString, QString> BlackBerryConfiguration::qnxEnv() const
{
    return m_qnxEnv;
}

void BlackBerryConfiguration::createConfigurationPerQtVersion(
        const FileName &qmakePath, Qnx::QnxArchitecture arch)
{
    QnxAbstractQtVersion *version = createQtVersion(qmakePath, arch);
    ToolChain *toolChain = createGccToolChain(version);
    Kit *kit = createKit(version, toolChain);

    if (version && toolChain && kit) {
        // register
        QtVersionManager::addVersion(version);
        ToolChainManager::registerToolChain(toolChain);
        KitManager::registerKit(kit);
    }
}

QnxAbstractQtVersion *BlackBerryConfiguration::createQtVersion(
        const FileName &qmakePath, Qnx::QnxArchitecture arch)
{
    QnxAbstractQtVersion *version = new BlackBerryQtVersion(
            arch, qmakePath, true, QString(), m_ndkEnvFile.toString());
    version->setDisplayName(tr("Qt %1 for %2 %3 - %4").arg(
            version->qtVersionString(), version->platformDisplayName(),
            version->archString(), m_targetName));
    return version;
}

GccToolChain *BlackBerryConfiguration::createGccToolChain(QnxAbstractQtVersion *version)
{
    GccToolChain* toolChain = new GccToolChain(
            QLatin1String(ProjectExplorer::Constants::GCC_TOOLCHAIN_ID), ToolChain::AutoDetection);
    //: QCC is the compiler for QNX.
    toolChain->setDisplayName(tr("QCC for Qt %1 for %2 %3 - %4").arg(
            version->qtVersionString(), version->platformDisplayName(),
            version->archString(), m_targetName));
    toolChain->setCompilerCommand(m_gccCompiler);
    QList<Abi> abis = version->qtAbis();
    if (!abis.isEmpty())
        toolChain->setTargetAbi(abis.first());
    return toolChain;
}

Kit *BlackBerryConfiguration::createKit(QnxAbstractQtVersion *version, ToolChain *toolChain)
{
    Kit *kit = new Kit;
    bool isSimulator = version->architecture() == X86;

    QtKitInformation::setQtVersion(kit, version);
    ToolChainKitInformation::setToolChain(kit, toolChain);

    Debugger::DebuggerItem debugger;
    debugger.setCommand(isSimulator ? m_simulatorDebugger : m_deviceDebugger);
    debugger.setEngineType(Debugger::GdbEngineType);
    debugger.setAutoDetected(true);
    debugger.setAbi(toolChain->targetAbi());
    debugger.setDisplayName(tr("Debugger for Qt %1 for %2 %3 - %4").arg(
            version->qtVersionString(), version->platformDisplayName(),
            version->archString(), m_targetName));
    Debugger::DebuggerKitInformation::setDebugger(kit, debugger);

    if (isSimulator)
        Qt4ProjectManager::QmakeKitInformation::setMkspec(
                 kit, FileName::fromString(QLatin1String("blackberry-x86-qcc")));

    DeviceTypeKitInformation::setDeviceTypeId(kit, Constants::QNX_BB_OS_TYPE);
    SysRootKitInformation::setSysRoot(kit, m_sysRoot);

    kit->setDisplayName(tr("%1 %2 - Qt %3 - %4").arg(
            version->platformDisplayName(), isSimulator ? tr("Simulator") : tr("Device"),
            version->qtVersionString(), m_targetName));
    kit->setIconPath(FileName::fromString(QLatin1String(Constants::QNX_BB_CATEGORY_ICON)));

    kit->setAutoDetected(true);
    kit->setMutable(DeviceKitInformation::id(), true);

    kit->setSticky(QtKitInformation::id(), true);
    kit->setSticky(ToolChainKitInformation::id(), true);
    kit->setSticky(DeviceTypeKitInformation::id(), true);
    kit->setSticky(SysRootKitInformation::id(), true);
    kit->setSticky(Debugger::DebuggerKitInformation::id(), true);
    kit->setSticky(Qt4ProjectManager::QmakeKitInformation::id(), true);

    return kit;
}

bool BlackBerryConfiguration::activate()
{
    if (!isValid()) {
        if (m_isAutoDetected)
            return false;

        QString errorMessage = tr("The following errors occurred while activating target: %1").arg(m_targetName);
        if (m_qmake4BinaryFile.isEmpty() && m_qmake5BinaryFile.isEmpty())
            errorMessage += QLatin1Char('\n') + tr("- No Qt version found.");

        if (m_gccCompiler.isEmpty())
            errorMessage += QLatin1Char('\n') + tr("- No GCC compiler found.");

        if (m_deviceDebugger.isEmpty())
            errorMessage += QLatin1Char('\n') + tr("- No GDB debugger found for BB10 Device.");

        if (!m_simulatorDebugger.isEmpty())
            errorMessage += QLatin1Char('\n') + tr("- No GDB debugger found for BB10 Simulator.");

        QMessageBox::warning(0, tr("Cannot Set up BB10 Configuration"),
                             errorMessage, QMessageBox::Ok);
        return false;
    }

    if (isActive())
        return true;

    deactivate(); // cleaning-up artifacts autodetected by old QtCreator versions

    if (!m_qmake4BinaryFile.isEmpty()) {
        createConfigurationPerQtVersion(m_qmake4BinaryFile, Qnx::ArmLeV7);
        createConfigurationPerQtVersion(m_qmake4BinaryFile, Qnx::X86);
    }

    if (!m_qmake5BinaryFile.isEmpty()) {
        createConfigurationPerQtVersion(m_qmake5BinaryFile, Qnx::ArmLeV7);
        createConfigurationPerQtVersion(m_qmake5BinaryFile, Qnx::X86);
    }

    return true;
}

QList<BaseQtVersion *> BlackBerryConfiguration::findRegisteredQtVersions() const
{
    QList<BaseQtVersion *> versions;
    foreach (BaseQtVersion *version, QtVersionManager::versions()) {
        if (version->type() == QLatin1String(Constants::QNX_BB_QT)) {
            QnxAbstractQtVersion *qnxVersion = dynamic_cast<QnxAbstractQtVersion *>(version);
            if (qnxVersion  &&  qnxVersion->isAutodetected()
                    && (qnxVersion->qmakeCommand() == qmake4BinaryFile()
                    || qnxVersion->qmakeCommand() == qmake5BinaryFile()))
                versions << qnxVersion;
        }
    }
    return versions;
}

void BlackBerryConfiguration::deactivate()
{
    QList<BaseQtVersion *> versions = findRegisteredQtVersions();
    QList<ToolChain *> toolChains;
    foreach (Kit *kit, KitManager::kits()) {
        if (kit->isAutoDetected()) {
            BaseQtVersion *version = QtKitInformation::qtVersion(kit);
            if (versions.contains(version)) {
                ToolChain *toolChain = ToolChainKitInformation::toolChain(kit);
                if (toolChain)
                    toolChains << toolChain;
                KitManager::deregisterKit(kit);
            }
        }
    }

    // unable to deregistering debuggers because of missing API

    foreach (ToolChain *toolChain, ToolChainManager::toolChains())
        if (toolChain->isAutoDetected()
                && (toolChains.contains(toolChain) || toolChain->compilerCommand() == m_gccCompiler))
            ToolChainManager::deregisterToolChain(toolChain);

    foreach (BaseQtVersion *version, versions)
        QtVersionManager::removeVersion(version);
}

} // namespace Internal
} // namespace Qnx
<|endoftext|>


<commit_before>//===- SimplifyCFG.cpp - CFG Simplification Pass --------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements dead code elimination and basic block merging.
//
// Specifically, this:
//   * removes basic blocks with no predecessors
//   * merges a basic block into its predecessor if there is only one and the
//     predecessor only has one successor.
//   * Eliminates PHI nodes for basic blocks with a single predecessor
//   * Eliminates a basic block that only contains an unconditional branch
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Module.h"
#include "llvm/Support/CFG.h"
#include "llvm/Pass.h"
#include "llvm/ADT/Statistic.h"
#include <set>
using namespace llvm;

namespace {
  Statistic<> NumSimpl("cfgsimplify", "Number of blocks simplified");

  struct CFGSimplifyPass : public FunctionPass {
    virtual bool runOnFunction(Function &F);
  };
  RegisterOpt<CFGSimplifyPass> X("simplifycfg", "Simplify the CFG");
}

// Public interface to the CFGSimplification pass
FunctionPass *llvm::createCFGSimplificationPass() {
  return new CFGSimplifyPass();
}

static bool MarkAliveBlocks(BasicBlock *BB, std::set<BasicBlock*> &Reachable) {
  if (Reachable.count(BB)) return false;
  Reachable.insert(BB);

  bool Changed = ConstantFoldTerminator(BB);
  for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB); SI != SE; ++SI)
    MarkAliveBlocks(*SI, Reachable);

  return Changed;
}

// It is possible that we may require multiple passes over the code to fully
// simplify the CFG.
//
bool CFGSimplifyPass::runOnFunction(Function &F) {
  std::set<BasicBlock*> Reachable;
  bool Changed = MarkAliveBlocks(F.begin(), Reachable);

  // If there are unreachable blocks in the CFG...
  if (Reachable.size() != F.size()) {
    assert(Reachable.size() < F.size());
    NumSimpl += F.size()-Reachable.size();

    // Loop over all of the basic blocks that are not reachable, dropping all of
    // their internal references...
    for (Function::iterator BB = ++F.begin(), E = F.end(); BB != E; ++BB)
      if (!Reachable.count(BB)) {
        for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB); SI!=SE; ++SI)
          if (Reachable.count(*SI))
            (*SI)->removePredecessor(BB);
        BB->dropAllReferences();
      }

    for (Function::iterator I = ++F.begin(); I != F.end();)
      if (!Reachable.count(I))
        I = F.getBasicBlockList().erase(I);
      else
        ++I;

    Changed = true;
  }

  bool LocalChange = true;
  while (LocalChange) {
    LocalChange = false;

    // Loop over all of the basic blocks (except the first one) and remove them
    // if they are unneeded...
    //
    for (Function::iterator BBIt = ++F.begin(); BBIt != F.end(); ) {
      if (SimplifyCFG(BBIt++)) {
        LocalChange = true;
        ++NumSimpl;
      }
    }
    Changed |= LocalChange;
  }

  return Changed;
}
<commit_msg>Turn store -> null/undef into the LLVM unreachable instruction!  This simple change hacks off 10K of bytecode from perlbmk (.5%) even though the front-end is not generating them yet and we are not optimizing the resultant code. This isn't too bad.<commit_after>//===- SimplifyCFG.cpp - CFG Simplification Pass --------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements dead code elimination and basic block merging.
//
// Specifically, this:
//   * removes basic blocks with no predecessors
//   * merges a basic block into its predecessor if there is only one and the
//     predecessor only has one successor.
//   * Eliminates PHI nodes for basic blocks with a single predecessor
//   * Eliminates a basic block that only contains an unconditional branch
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Constants.h"
#include "llvm/Instructions.h"
#include "llvm/Module.h"
#include "llvm/Support/CFG.h"
#include "llvm/Pass.h"
#include "llvm/ADT/Statistic.h"
#include <set>
using namespace llvm;

namespace {
  Statistic<> NumSimpl("cfgsimplify", "Number of blocks simplified");

  struct CFGSimplifyPass : public FunctionPass {
    virtual bool runOnFunction(Function &F);
  };
  RegisterOpt<CFGSimplifyPass> X("simplifycfg", "Simplify the CFG");
}

// Public interface to the CFGSimplification pass
FunctionPass *llvm::createCFGSimplificationPass() {
  return new CFGSimplifyPass();
}

static bool MarkAliveBlocks(BasicBlock *BB, std::set<BasicBlock*> &Reachable) {
  if (Reachable.count(BB)) return false;
  Reachable.insert(BB);

  // Do a quick scan of the basic block, turning any obviously unreachable
  // instructions into LLVM unreachable insts.  The instruction combining pass
  // canonnicalizes unreachable insts into stores to null or undef.
  for (BasicBlock::iterator BBI = BB->begin(), E = BB->end(); BBI != E; ++BBI)
    if (StoreInst *SI = dyn_cast<StoreInst>(BBI))
      if (isa<ConstantPointerNull>(SI->getOperand(1)) ||
          isa<UndefValue>(SI->getOperand(1))) {
        // Loop over all of the successors, removing BB's entry from any PHI
        // nodes.
        for (succ_iterator I = succ_begin(BB), SE = succ_end(BB); I != SE; ++I)
          (*I)->removePredecessor(BB);

        new UnreachableInst(SI);
        std::cerr << "Inserted UNREACHABLE instruction!\n";

        // All instructions after this are dead.
        for (; BBI != E; ) {
          if (!BBI->use_empty())
            BBI->replaceAllUsesWith(UndefValue::get(BBI->getType()));
          BB->getInstList().erase(BBI++);
        }
        break;
      }

  bool Changed = ConstantFoldTerminator(BB);
  for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB); SI != SE; ++SI)
    MarkAliveBlocks(*SI, Reachable);

  return Changed;
}

// It is possible that we may require multiple passes over the code to fully
// simplify the CFG.
//
bool CFGSimplifyPass::runOnFunction(Function &F) {
  std::set<BasicBlock*> Reachable;
  bool Changed = MarkAliveBlocks(F.begin(), Reachable);

  // If there are unreachable blocks in the CFG...
  if (Reachable.size() != F.size()) {
    assert(Reachable.size() < F.size());
    NumSimpl += F.size()-Reachable.size();

    // Loop over all of the basic blocks that are not reachable, dropping all of
    // their internal references...
    for (Function::iterator BB = ++F.begin(), E = F.end(); BB != E; ++BB)
      if (!Reachable.count(BB)) {
        for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB); SI!=SE; ++SI)
          if (Reachable.count(*SI))
            (*SI)->removePredecessor(BB);
        BB->dropAllReferences();
      }

    for (Function::iterator I = ++F.begin(); I != F.end();)
      if (!Reachable.count(I))
        I = F.getBasicBlockList().erase(I);
      else
        ++I;

    Changed = true;
  }

  bool LocalChange = true;
  while (LocalChange) {
    LocalChange = false;

    // Loop over all of the basic blocks (except the first one) and remove them
    // if they are unneeded...
    //
    for (Function::iterator BBIt = ++F.begin(); BBIt != F.end(); ) {
      if (SimplifyCFG(BBIt++)) {
        LocalChange = true;
        ++NumSimpl;
      }
    }
    Changed |= LocalChange;
  }

  return Changed;
}
<|endoftext|>


<commit_before>/*
 * Copyright © 2012 Intel Corporation
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 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
 * 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, see <http://www.gnu.org/licenses/>.
 *
 * Author: Benjamin Segovia <benjamin.segovia@intel.com>
 */

 /*
  * Authors:
  *   Keith Whitwell <keith@tungstengraphics.com>
  */

// #include "brw_context.h"
#include "brw_defines.h"
#include "brw_eu.h"

#include <stdlib.h>
#include <assert.h>
#include <string.h>

// #include "glsl/ralloc.h"

<commit_msg>Removed unused file<commit_after><|endoftext|>


<commit_before>// request symbols
#include "cling/Interpreter/Interpreter.h"
#include "cling/Interpreter/CValuePrinter.h"
#include "cling/Interpreter/DynamicExprInfo.h"
#include "cling/Interpreter/InterpreterCallbacks.h"
#include "cling/Interpreter/LookupHelper.h"
#include "cling/Interpreter/ValuePrinter.h"
#include "cling/Interpreter/ValuePrinterInfo.h"
#include "cling/UserInterface/UserInterface.h"

#include "clang/AST/Type.h"

#include "llvm/Support/raw_ostream.h"

namespace cling {
void libcling__symbol_requester() {
   const char* const argv[] = {"libcling__symbol_requester", 0};
   cling::Interpreter I(1, argv);
   cling::UserInterface U(I);
   cling::ValuePrinterInfo VPI(0, 0); // asserts, but we don't call.
   printValuePublicDefault(llvm::outs(), 0, VPI);
   cling_PrintValue(0, 0, 0);
   flushOStream(llvm::outs());
   LookupHelper h(0);
   h.findType("");
   h.findScope("");
   h.findFunctionProto(0, "", "");
   h.findFunctionArgs(0, "", "");
   cling::runtime::internal::DynamicExprInfo DEI(0,0,false);
   DEI.getExpr();
   cling::InterpreterCallbacks cb(0);
}

}
<commit_msg>Put the symbol requester func into the proper namespace!<commit_after>// request symbols
#include "cling/Interpreter/Interpreter.h"
#include "cling/Interpreter/CValuePrinter.h"
#include "cling/Interpreter/DynamicExprInfo.h"
#include "cling/Interpreter/InterpreterCallbacks.h"
#include "cling/Interpreter/LookupHelper.h"
#include "cling/Interpreter/ValuePrinter.h"
#include "cling/Interpreter/ValuePrinterInfo.h"
#include "cling/UserInterface/UserInterface.h"

#include "clang/AST/Type.h"

#include "llvm/Support/raw_ostream.h"

namespace cling {
namespace internal {
void libcling__symbol_requester() {
   const char* const argv[] = {"libcling__symbol_requester", 0};
   cling::Interpreter I(1, argv);
   cling::UserInterface U(I);
   cling::ValuePrinterInfo VPI(0, 0); // asserts, but we don't call.
   printValuePublicDefault(llvm::outs(), 0, VPI);
   cling_PrintValue(0, 0, 0);
   flushOStream(llvm::outs());
   LookupHelper h(0);
   h.findType("");
   h.findScope("");
   h.findFunctionProto(0, "", "");
   h.findFunctionArgs(0, "", "");
   cling::runtime::internal::DynamicExprInfo DEI(0,0,false);
   DEI.getExpr();
   cling::InterpreterCallbacks cb(0);
}
}
}
<|endoftext|>


<commit_before><commit_msg>loplugin:unreffun<commit_after><|endoftext|>


<commit_before><commit_msg>Unused variable.<commit_after><|endoftext|>


<commit_before>// (c) Ivan Gagis
// e-mail: igagis@gmail.com
// Version: 1

// Description:
//          Network Thread class

#pragma once

#include <ting/Array.hpp>
#include <ting/Buffer.hpp>
#include <ting/types.hpp>
#include <ting/debug.hpp>
#include <ting/Thread.hpp>
#include <ting/Socket.hpp>
#include <ting/WaitSet.hpp>

#include "../util/util.hpp"

//forward declarations
//...

namespace cliser{

class NetworkThread : public ting::Thread{
    friend class ConnectToServerMessage;
	friend class DisconnectFromServerMessage;
    friend class SendNetworkDataToServerMessage;

    ting::TCPSocket socket;
    ting::WaitSet waitSet;

    cliser::NetworkReceiverState netReceiverState;

public:
    NetworkThread() :
            waitSet(2) //1 for socket and 1 for queue
    {
//        TRACE(<<"C_NetworkThread::C_NetworkThread(): enter"<<std::endl)
		this->waitSet.Add(&this->queue, ting::Waitable::READ);
    }

    ~NetworkThread(){
//        TRACE(<<"C_NetworkThread::~C_NetworkThread(): invoked"<<std::endl)
		this->waitSet.Remove(&this->queue);
    }

	//send connection request message to the thread
	void Connect_ts(const std::string& host, ting::u16 port);

	//send disconnection request message to the thread
	void Disconnect_ts();

	virtual void OnDataReceived(ting::Array<ting::byte> data) = 0;

	enum EConnectFailReason{
		SUCCESS,
		ALREADY_CONNECTED,
		COULD_NOT_RESOLVE_HOST_IP,
		SOME_ERROR
	};

	virtual void OnConnect(EConnectFailReason failReason) = 0;

	virtual void OnDisconnect() = 0;

	void SendData_ts(ting::Array<ting::byte> data);

private:
	//override
    void Run();

    void HandleSocketActivity();

	void HandleDisconnection();
};

class ConnectToServerMessage : public ting::Message{
    NetworkThread* nt;
	std::string host;
	ting::u16 port;
  public:
    ConnectToServerMessage(
			NetworkThread* netwrokThread,
			const std::string& theHost,
			ting::u16 thePort
		) :
            nt(netwrokThread),
			host(theHost),
			port(thePort)
    {
        ASSERT(this->nt)
    }

    //override
    void Handle();
};

class DisconnectFromServerMessage : public ting::Message{
    NetworkThread* nt;

  public:
    DisconnectFromServerMessage(NetworkThread* netwrokThread) :
            nt(netwrokThread)
    {
        ASSERT(this->nt)
    }

    //override
    void Handle();
};

class SendNetworkDataToServerMessage : public ting::Message{
    NetworkThread* nt;
    ting::Array<ting::byte> data;
  public:
    SendNetworkDataToServerMessage(NetworkThread* netwrokThread, ting::Array<ting::byte> &dataToSend) :
            nt(netwrokThread),
            data(dataToSend)
    {
        ASSERT(this->nt)
    }

    //override
    void Handle();
};

}//~namespace
<commit_msg>use ting::MsgThread<commit_after>// (c) Ivan Gagis
// e-mail: igagis@gmail.com
// Version: 1

// Description:
//          Network Thread class

#pragma once

#include <ting/Array.hpp>
#include <ting/Buffer.hpp>
#include <ting/types.hpp>
#include <ting/debug.hpp>
#include <ting/Thread.hpp>
#include <ting/Socket.hpp>
#include <ting/WaitSet.hpp>

#include "../util/util.hpp"

//forward declarations
//...

namespace cliser{

class NetworkThread : public ting::MsgThread{
    friend class ConnectToServerMessage;
	friend class DisconnectFromServerMessage;
    friend class SendNetworkDataToServerMessage;

    ting::TCPSocket socket;
    ting::WaitSet waitSet;

    cliser::NetworkReceiverState netReceiverState;

public:
    NetworkThread() :
            waitSet(2) //1 for socket and 1 for queue
    {
//        TRACE(<<"C_NetworkThread::C_NetworkThread(): enter"<<std::endl)
		this->waitSet.Add(&this->queue, ting::Waitable::READ);
    }

    ~NetworkThread(){
//        TRACE(<<"C_NetworkThread::~C_NetworkThread(): invoked"<<std::endl)
		this->waitSet.Remove(&this->queue);
    }

	//send connection request message to the thread
	void Connect_ts(const std::string& host, ting::u16 port);

	//send disconnection request message to the thread
	void Disconnect_ts();

	virtual void OnDataReceived(ting::Array<ting::byte> data) = 0;

	enum EConnectFailReason{
		SUCCESS,
		ALREADY_CONNECTED,
		COULD_NOT_RESOLVE_HOST_IP,
		SOME_ERROR
	};

	virtual void OnConnect(EConnectFailReason failReason) = 0;

	virtual void OnDisconnect() = 0;

	void SendData_ts(ting::Array<ting::byte> data);

private:
	//override
    void Run();

    void HandleSocketActivity();

	void HandleDisconnection();
};

class ConnectToServerMessage : public ting::Message{
    NetworkThread* nt;
	std::string host;
	ting::u16 port;
  public:
    ConnectToServerMessage(
			NetworkThread* netwrokThread,
			const std::string& theHost,
			ting::u16 thePort
		) :
            nt(netwrokThread),
			host(theHost),
			port(thePort)
    {
        ASSERT(this->nt)
    }

    //override
    void Handle();
};

class DisconnectFromServerMessage : public ting::Message{
    NetworkThread* nt;

  public:
    DisconnectFromServerMessage(NetworkThread* netwrokThread) :
            nt(netwrokThread)
    {
        ASSERT(this->nt)
    }

    //override
    void Handle();
};

class SendNetworkDataToServerMessage : public ting::Message{
    NetworkThread* nt;
    ting::Array<ting::byte> data;
  public:
    SendNetworkDataToServerMessage(NetworkThread* netwrokThread, ting::Array<ting::byte> &dataToSend) :
            nt(netwrokThread),
            data(dataToSend)
    {
        ASSERT(this->nt)
    }

    //override
    void Handle();
};

}//~namespace
<|endoftext|>


<commit_before>/*!
 * \file UFCallMapAndBounds_test.cc
 *
 * \brief Test for the UFCallMapAndBounds class.
 *
 * \date Started: 7/30/2013
 *
 * \authors Michelle Strout and Mark Heim
 *
 * Copyright (c) 2013, Colorado State University

 * All rights reserved.

 * See ../../COPYING for details.

 */

#include "expression.h"
#include "UFCallMapAndBounds.h"
#include "set_relation.h"

#include <gtest/gtest.h>
#include <utility>
#include <iostream>
#include <fstream>

using iegenlib::UFCallMapAndBounds;
using iegenlib::Exp;
using iegenlib::TupleVarTerm;
using iegenlib::Term;
using iegenlib::VarTerm;
using iegenlib::UFCallTerm;
using iegenlib::Set;
using iegenlib::TupleExpTerm;

#pragma mark UFCallMapAndBoundsDomainNoTupleVars
// Test the UFCallMapAndBounds methods related to bounding by domain.
// There should be no temporary variables introduced.
// In this example the parameter expressions do not use tuple vars.
TEST(UFCallMapAndBoundsTest, UFCallMapAndBoundsDomainNoTupleVars) {

    Set* domain = new Set("{[j] : lb_j <= j && j <= ub_j } ");
    Set* range = new Set("{[i] : lb_i <= i && i <= ub_i } ");

    // declare f and g as non-bijective functions
    iegenlib::setCurrEnv();
    iegenlib::appendCurrEnv("f", domain, range, false,
                            iegenlib::Monotonic_NONE);

    // Assume original set is
    // {[x,y] : x = f(N)}
    Set* original_set = new Set("{[x,y] : x = f(N)}");
    UFCallMapAndBounds ufcall_map(original_set->getTupleDecl());

    // Construct the UFCallTerm f(N)
    Exp *e1 = new Exp();  // N
    e1->addTerm(new VarTerm("N"));

    UFCallTerm* ufcallptr = new UFCallTerm("f", 1);
    ufcallptr->setParamExp(0,e1);

    // boundByDomain is what we are testing
    ufcall_map.boundByDomain(ufcallptr);

    // boundByDomain should modify the constraints UFCallMapAndBounds
    // is maintaining.
    EXPECT_EQ(0u, ufcall_map.numTempVars());
    Set* constraints = ufcall_map.cloneConstraints();
    Set* expected = new Set("{[x,y] : lb_j<=N && N<=ub_j}");
    EXPECT_EQ(expected->toString(), constraints->toString());

    delete constraints;
    delete expected;
    delete original_set;
    delete ufcallptr;
}

#pragma mark UFCallMapAndBoundsDomainWithTupleVars
// Test the UFCallMapAndBounds methods related to bounding by domain.
// There should be no temporary variables introduced.
// In this example the parameter expressions should use tuple vars.
TEST(UFCallMapAndBoundsTest, UFCallMapAndBoundsDomainWithTupleVars) {

    Set* domain = new Set("{[j] : lb_j <= j && j <= ub_j } ");
    Set* range = new Set("{[i] : lb_i <= i && i <= ub_i } ");

    // declare f and g as non-bijective functions
    iegenlib::setCurrEnv();
    iegenlib::appendCurrEnv("f", domain, range, false,
                            iegenlib::Monotonic_NONE);

    // Assume original set is
    // {[x,y] : x = f(N)}
    Set* original_set = new Set("{[x,y] : x = f(x+y) && 4=f(N)}");
    UFCallMapAndBounds ufcall_map(original_set->getTupleDecl());

    // Construct the UFCallTerm f(x+y)
    Exp *e1 = new Exp();  // x+y
    e1->addTerm(new TupleVarTerm(0));
    e1->addTerm(new TupleVarTerm(1));

    UFCallTerm* ufcallptr = new UFCallTerm("f", 1);
    ufcallptr->setParamExp(0,e1);

    // boundByDomain is what we are testing
    ufcall_map.boundByDomain(ufcallptr);

    // boundByDomain should modify the constraints UFCallMapAndBounds
    // is maintaining.
    EXPECT_EQ(0u, ufcall_map.numTempVars());
    Set* constraints = ufcall_map.cloneConstraints();
    Set* expected = new Set("{[x,y] : lb_j<=x+y && x+y<=ub_j}");
    EXPECT_EQ(expected->toString(), constraints->toString());

    // Construct the UFCallTerm f(N)
    e1 = new Exp();  // N
    e1->addTerm(new VarTerm("N"));

    UFCallTerm* ufcallptr2 = new UFCallTerm("f", 1);
    ufcallptr2->setParamExp(0,e1);

     // boundByDomain is what we are testing
    ufcall_map.boundByDomain(ufcallptr2);

    // boundByDomain should modify the constraints UFCallMapAndBounds
    // is maintaining.
    EXPECT_EQ(0u, ufcall_map.numTempVars());
    delete constraints;
    constraints = ufcall_map.cloneConstraints();
    delete expected;
    expected = new Set("{[x,y]: lb_j<=x+y && x+y<=ub_j && lb_j<=N && N<=ub_j}");
    EXPECT_EQ(expected->toString(), constraints->toString());

    delete constraints;
    delete expected;
    delete original_set;
    delete ufcallptr;
    delete ufcallptr2;
}

#pragma mark UFCallMapAndBoundsDomain2D
// Test the UFCallMapAndBounds methods related to bounding by domain.
// There should be no temporary variables introduced.
// Here the domain is 2D.
TEST(UFCallMapAndBoundsTest, UFCallMapAndBoundsDomain2D) {

    Set* range = new Set("{[0,t] : lb_t <= t && t <= ub_t } "
                         "union {[1,s] : lb_s <= s && s <= ub_s }");

    Set* domain = new Set("{[p,v] : lb_p <= p && p <= ub_p && lb_v <= v "
                         "&& v <= ub_v } "
                         "union {[q,w] : lb_q <= q && q <= ub_q "
                         "&& lb_w <= w && w <= ub_w }");

    // declare f and g as non-bijective functions
    iegenlib::setCurrEnv();
    iegenlib::appendCurrEnv("f", domain, range, false,
                            iegenlib::Monotonic_NONE);

    // Assume original set is
    // {[x,y] : x = f(N,y)}
    Set* original_set = new Set("{[x,y] : x = f(N,y)}");
    UFCallMapAndBounds ufcall_map(original_set->getTupleDecl());

    // Construct the UFCallTerm f(N,y)
    Exp *e1 = new Exp();  // N
    e1->addTerm(new VarTerm("N"));

    UFCallTerm* ufcallptr = new UFCallTerm("f", 2);
    ufcallptr->setParamExp(0,e1);
    e1 = new Exp(); // y
    e1->addTerm(new TupleVarTerm(7,1));
    ufcallptr->setParamExp(1,e1);

    // boundByDomain is what we are testing
    ufcall_map.boundByDomain(ufcallptr);

    // boundByDomain should modify the constraints UFCallMapAndBounds
    // is maintaining.
    EXPECT_EQ(0u, ufcall_map.numTempVars());
    Set* constraints = ufcall_map.cloneConstraints();
    Set* expected = new Set("{[x,y] : lb_p <= N && N <= ub_p && lb_v <= 7 y "
                         "&& 7 y <= ub_v } "
                         "union {[x,y] : lb_q <= N && N <= ub_q "
                         "&& lb_w <= 7 y && 7 y <= ub_w }");
    EXPECT_EQ(expected->toString(), constraints->toString());

    delete constraints;
    delete expected;
    delete original_set;
    delete ufcallptr;
}

#pragma mark UFCallMapAndBoundsRange1D
// Range is 1D.  One temporary variable should be created.
TEST(UFCallMapAndBoundsTest, UFCallMapAndBoundsRange1D) {

    Set* range = new Set("{[i] : lb_i <= i && i <= ub_i } ");

    Set* domain = new Set("{[p,v] : lb_p <= p && p <= ub_p && lb_v <= v "
                         "&& v <= ub_v } "
                         "union {[q,w] : lb_q <= q && q <= ub_q "
                         "&& lb_w <= w && w <= ub_w }");

    // declare f as a non-bijective function.
    iegenlib::setCurrEnv();
    iegenlib::appendCurrEnv("f", domain, range, false,
                            iegenlib::Monotonic_NONE);

    // Assume original set is
    // {[x,y] : 7 + x = f(N,y)}
    Set* original_set = new Set("{[x,y] : x = f(N,y)}");
    UFCallMapAndBounds ufcall_map(original_set->getTupleDecl());

    // Construct the UFCallTerm f(N,7 y)
    Exp *e1 = new Exp();  // N
    e1->addTerm(new VarTerm("N"));

    UFCallTerm* ufcallptr = new UFCallTerm("f", 2);
    ufcallptr->setParamExp(0,e1);
    e1 = new Exp(); // y
    e1->addTerm(new TupleVarTerm(7,1));
    ufcallptr->setParamExp(1,e1);

    // bound by range, method we are testing
    TupleExpTerm* t = ufcall_map.boundByRange( ufcallptr );
    delete t;

    // boundByRange should modify the constraints UFCallMapAndBounds
    // is maintaining.  It should introduce one temporary.
    EXPECT_EQ(1u, ufcall_map.numTempVars());
    Set* constraints = ufcall_map.cloneConstraints();
    Set* expected
        = new Set("{[x,y,tv2] : lb_i <= tv2 && tv2 <= ub_i }");
    EXPECT_EQ(expected->toString(), constraints->toString());
    UFCallTerm* fetched_ufcall = ufcall_map.cloneUFCall(2); // query tv2
    EXPECT_EQ("f(N, 7 __tv1)", fetched_ufcall->toString() );

    delete original_set;
    delete expected;
    delete ufcallptr;
    delete constraints;
    delete fetched_ufcall;
}

#pragma mark UFCallMapAndBoundsRange2D
// Test the UFCallMapAndBounds methods that generate bounds for
// a multi-dimensional expression.
TEST(UFCallMapAndBoundsTest, UFCallMapAndBoundsRange2D) {

    Set* range = new Set("{[0,t] : lb_t <= t && t <= ub_t } "
                         "union {[1,s] : lb_s <= s && s <= ub_s }");

    Set* domain = new Set("{[p,v] : lb_p <= p && p <= ub_p && lb_v <= v "
                         "&& v <= ub_v } "
                         "union {[q,w] : lb_q <= q && q <= ub_q "
                         "&& lb_w <= w && w <= ub_w }");

    // declare f as a non-bijective function.
    iegenlib::setCurrEnv();
    iegenlib::appendCurrEnv("f", domain, range, false,
                            iegenlib::Monotonic_NONE);

    // Assume original set is
    // {[x,y] : (7 + x,y) = f(N,y)}
    Set* original_set = new Set("{[x,y] : (7+x,y) = f(N,y)}");
    UFCallMapAndBounds ufcall_map(original_set->getTupleDecl());

    // Construct the UFCallTerm f(N,7 y)
    Exp *e1 = new Exp();  // N
    e1->addTerm(new VarTerm("N"));

    UFCallTerm* ufcallptr = new UFCallTerm("f", 2);
    ufcallptr->setParamExp(0,e1);
    e1 = new Exp(); // y
    e1->addTerm(new TupleVarTerm(7,1));
    ufcallptr->setParamExp(1,e1);

    // bound by range, method we are testing
    TupleExpTerm* t = ufcall_map.boundByRange( ufcallptr );
    delete t;

    // boundByRange should modify the constraints UFCallMapAndBounds
    // is maintaining.  It should introduce two temporaries.
    EXPECT_EQ(2u, ufcall_map.numTempVars());
    Set* constraints = ufcall_map.cloneConstraints();
    Set* expected = new Set("{[x,y,tv2,tv3] : "
                    "tv2=0 && lb_t <= tv3 && tv3 <= ub_t}"
                    " union {[x,y,tv2,tv3] : "
                    "tv2=1 && lb_s <= tv3 && tv3 <= ub_s }");
    EXPECT_EQ(expected->toString(), constraints->toString());
    UFCallTerm* fetched_ufcall = ufcall_map.cloneUFCall(2); // tv2 = ?
    //EXPECT_EQ("f(N, 7 __tv1)", fetched_ufcall->toString() );
    EXPECT_EQ("f(N, 7 __tv1)[0]", fetched_ufcall->toString() );

    delete original_set;
    delete expected;
    delete ufcallptr;
    delete fetched_ufcall;
    delete constraints;
}

<commit_msg>UFCallMap in separate files<commit_after>/*!
 * \file UFCallMapAndBounds_test.cc
 *
 * \brief Test for the UFCallMapAndBounds class.
 *
 * \date Started: 7/30/2013
 *
 * \authors Michelle Strout and Mark Heim
 *
 * Copyright (c) 2013, Colorado State University

 * All rights reserved.

 * See ../../COPYING for details.

 */

#include "expression.h"
#include "UFCallMapAndBounds.h"
#include "set_relation.h"

#include <gtest/gtest.h>
#include <utility>
#include <iostream>
#include <fstream>

using iegenlib::UFCallMapAndBounds;
using iegenlib::Exp;
using iegenlib::TupleVarTerm;
using iegenlib::Term;
using iegenlib::VarTerm;
using iegenlib::UFCallTerm;
using iegenlib::Set;
using iegenlib::TupleExpTerm;

#pragma mark UFCallMapAndBoundsDomainNoTupleVars
// Test the UFCallMapAndBounds methods related to bounding by domain.
// There should be no temporary variables introduced.
// In this example the parameter expressions do not use tuple vars.
TEST(UFCallMapAndBoundsTest, UFCallMapAndBoundsDomainNoTupleVars) {

    Set* domain = new Set("{[j] : lb_j <= j && j <= ub_j } ");
    Set* range = new Set("{[i] : lb_i <= i && i <= ub_i } ");

    // declare f and g as non-bijective functions
    iegenlib::setCurrEnv();
    iegenlib::appendCurrEnv("f", domain, range, false,
                            iegenlib::Monotonic_NONE);

    // Assume original set is
    // {[x,y] : x = f(N)}
    Set* original_set = new Set("{[x,y] : x = f(N)}");
    UFCallMapAndBounds ufcall_map(original_set->getTupleDecl());

    // Construct the UFCallTerm f(N)
    Exp *e1 = new Exp();  // N
    e1->addTerm(new VarTerm("N"));

    UFCallTerm* ufcallptr = new UFCallTerm("f", 1);
    ufcallptr->setParamExp(0,e1);

    // boundByDomain is what we are testing
    ufcall_map.boundByDomain(ufcallptr);

    // boundByDomain should modify the constraints UFCallMapAndBounds
    // is maintaining.
    EXPECT_EQ(0u, ufcall_map.numTempVars());
    Set* constraints = ufcall_map.cloneConstraints();
    Set* expected = new Set("{[x,y] : lb_j<=N && N<=ub_j}");
    EXPECT_EQ(expected->toString(), constraints->toString());

    delete constraints;
    delete expected;
    delete original_set;
    delete ufcallptr;
}

#pragma mark UFCallMapAndBoundsDomainWithTupleVars
// Test the UFCallMapAndBounds methods related to bounding by domain.
// There should be no temporary variables introduced.
// In this example the parameter expressions should use tuple vars.
TEST(UFCallMapAndBoundsTest, UFCallMapAndBoundsDomainWithTupleVars) {

    Set* domain = new Set("{[j] : lb_j <= j && j <= ub_j } ");
    Set* range = new Set("{[i] : lb_i <= i && i <= ub_i } ");

    // declare f and g as non-bijective functions
    iegenlib::setCurrEnv();
    iegenlib::appendCurrEnv("f", domain, range, false,
                            iegenlib::Monotonic_NONE);

    // Assume original set is
    // {[x,y] : x = f(N)}
    Set* original_set = new Set("{[x,y] : x = f(x+y) && 4=f(N)}");
    UFCallMapAndBounds ufcall_map(original_set->getTupleDecl());

    // Construct the UFCallTerm f(x+y)
    Exp *e1 = new Exp();  // x+y
    e1->addTerm(new TupleVarTerm(0));
    e1->addTerm(new TupleVarTerm(1));

    UFCallTerm* ufcallptr = new UFCallTerm("f", 1);
    ufcallptr->setParamExp(0,e1);

    // boundByDomain is what we are testing
    ufcall_map.boundByDomain(ufcallptr);

    // boundByDomain should modify the constraints UFCallMapAndBounds
    // is maintaining.
    EXPECT_EQ(0u, ufcall_map.numTempVars());
    Set* constraints = ufcall_map.cloneConstraints();
    Set* expected = new Set("{[x,y] : lb_j<=x+y && x+y<=ub_j}");
    EXPECT_EQ(expected->toString(), constraints->toString());

    // Construct the UFCallTerm f(N)
    e1 = new Exp();  // N
    e1->addTerm(new VarTerm("N"));

    UFCallTerm* ufcallptr2 = new UFCallTerm("f", 1);
    ufcallptr2->setParamExp(0,e1);

     // boundByDomain is what we are testing
    ufcall_map.boundByDomain(ufcallptr2);

    // boundByDomain should modify the constraints UFCallMapAndBounds
    // is maintaining.
    EXPECT_EQ(0u, ufcall_map.numTempVars());
    delete constraints;
    constraints = ufcall_map.cloneConstraints();
    delete expected;
    expected = new Set("{[x,y]: lb_j<=x+y && x+y<=ub_j && lb_j<=N && N<=ub_j}");
    EXPECT_EQ(expected->toString(), constraints->toString());

    delete constraints;
    delete expected;
    delete original_set;
    delete ufcallptr;
    delete ufcallptr2;
}

#pragma mark UFCallMapAndBoundsDomain2D
// Test the UFCallMapAndBounds methods related to bounding by domain.
// There should be no temporary variables introduced.
// Here the domain is 2D.
TEST(UFCallMapAndBoundsTest, UFCallMapAndBoundsDomain2D) {

    Set* range = new Set("{[0,t] : lb_t <= t && t <= ub_t } "
                         "union {[1,s] : lb_s <= s && s <= ub_s }");

    Set* domain = new Set("{[p,v] : lb_p <= p && p <= ub_p && lb_v <= v "
                         "&& v <= ub_v } "
                         "union {[q,w] : lb_q <= q && q <= ub_q "
                         "&& lb_w <= w && w <= ub_w }");

    // declare f and g as non-bijective functions
    iegenlib::setCurrEnv();
    iegenlib::appendCurrEnv("f", domain, range, false,
                            iegenlib::Monotonic_NONE);

    // Assume original set is
    // {[x,y] : x = f(N,y)}
    Set* original_set = new Set("{[x,y] : x = f(N,y)}");
    UFCallMapAndBounds ufcall_map(original_set->getTupleDecl());

    // Construct the UFCallTerm f(N,y)
    Exp *e1 = new Exp();  // N
    e1->addTerm(new VarTerm("N"));

    UFCallTerm* ufcallptr = new UFCallTerm("f", 2);
    ufcallptr->setParamExp(0,e1);
    e1 = new Exp(); // y
    e1->addTerm(new TupleVarTerm(7,1));
    ufcallptr->setParamExp(1,e1);

    // boundByDomain is what we are testing
    ufcall_map.boundByDomain(ufcallptr);

    // boundByDomain should modify the constraints UFCallMapAndBounds
    // is maintaining.
    EXPECT_EQ(0u, ufcall_map.numTempVars());
    Set* constraints = ufcall_map.cloneConstraints();
    Set* expected = new Set("{[x,y] : lb_p <= N && N <= ub_p && lb_v <= 7 y "
                         "&& 7 y <= ub_v } "
                         "union {[x,y] : lb_q <= N && N <= ub_q "
                         "&& lb_w <= 7 y && 7 y <= ub_w }");
    EXPECT_EQ(expected->toString(), constraints->toString());

    delete constraints;
    delete expected;
    delete original_set;
    delete ufcallptr;
}

#pragma mark UFCallMapAndBoundsRange1D
// Range is 1D.  One temporary variable should be created.
TEST(UFCallMapAndBoundsTest, UFCallMapAndBoundsRange1D) {

    Set* range = new Set("{[i] : lb_i <= i && i <= ub_i } ");

    Set* domain = new Set("{[p,v] : lb_p <= p && p <= ub_p && lb_v <= v "
                         "&& v <= ub_v } "
                         "union {[q,w] : lb_q <= q && q <= ub_q "
                         "&& lb_w <= w && w <= ub_w }");

    // declare f as a non-bijective function.
    iegenlib::setCurrEnv();
    iegenlib::appendCurrEnv("f", domain, range, false,
                            iegenlib::Monotonic_NONE);

    // Assume original set is
    // {[x,y] : 7 + x = f(N,y)}
    Set* original_set = new Set("{[x,y] : x = f(N,y)}");
    UFCallMapAndBounds ufcall_map(original_set->getTupleDecl());

    // Construct the UFCallTerm f(N,7 y)
    Exp *e1 = new Exp();  // N
    e1->addTerm(new VarTerm("N"));

    UFCallTerm* ufcallptr = new UFCallTerm("f", 2);
    ufcallptr->setParamExp(0,e1);
    e1 = new Exp(); // y
    e1->addTerm(new TupleVarTerm(7,1));
    ufcallptr->setParamExp(1,e1);

    // bound by range, method we are testing
    TupleExpTerm* t = ufcall_map.boundByRange( ufcallptr );
    delete t;

    // boundByRange should modify the constraints UFCallMapAndBounds
    // is maintaining.  It should introduce one temporary.
    EXPECT_EQ(1u, ufcall_map.numTempVars());
    Set* constraints = ufcall_map.cloneConstraints();
    Set* expected
        = new Set("{[x,y,tv2] : lb_i <= tv2 && tv2 <= ub_i }");
    EXPECT_EQ(expected->toString(), constraints->toString());
    UFCallTerm* fetched_ufcall = ufcall_map.cloneUFCall(2); // query tv2
    EXPECT_EQ("f(N, 7 __tv1)", fetched_ufcall->toString() );

    delete original_set;
    delete expected;
    delete ufcallptr;
    delete constraints;
    delete fetched_ufcall;
}

#pragma mark UFCallMapAndBoundsRange2D
// Test the UFCallMapAndBounds methods that generate bounds for
// a multi-dimensional expression.
TEST(UFCallMapAndBoundsTest, UFCallMapAndBoundsRange2D) {

    Set* range = new Set("{[0,t] : lb_t <= t && t <= ub_t } "
                         "union {[1,s] : lb_s <= s && s <= ub_s }");

    Set* domain = new Set("{[p,v] : lb_p <= p && p <= ub_p && lb_v <= v "
                         "&& v <= ub_v } "
                         "union {[q,w] : lb_q <= q && q <= ub_q "
                         "&& lb_w <= w && w <= ub_w }");

    // declare f as a non-bijective function.
    iegenlib::setCurrEnv();
    iegenlib::appendCurrEnv("f", domain, range, false,
                            iegenlib::Monotonic_NONE);

    // Assume original set is
    // {[x,y] : (7 + x,y) = f(N,y)}
    Set* original_set = new Set("{[x,y] : (7+x,y) = f(N,y)}");
    UFCallMapAndBounds ufcall_map(original_set->getTupleDecl());

    // Construct the UFCallTerm f(N,7 y)
    Exp *e1 = new Exp();  // N
    e1->addTerm(new VarTerm("N"));

    UFCallTerm* ufcallptr = new UFCallTerm("f", 2);
    ufcallptr->setParamExp(0,e1);
    e1 = new Exp(); // y
    e1->addTerm(new TupleVarTerm(7,1));
    ufcallptr->setParamExp(1,e1);

    // bound by range, method we are testing
    TupleExpTerm* t = ufcall_map.boundByRange( ufcallptr );
    delete t;

    // boundByRange should modify the constraints UFCallMapAndBounds
    // is maintaining.  It should introduce two temporaries.
    EXPECT_EQ(2u, ufcall_map.numTempVars());
    Set* constraints = ufcall_map.cloneConstraints();
    Set* expected = new Set("{[x,y,tv2,tv3] : "
                    "tv2=0 && lb_t <= tv3 && tv3 <= ub_t}"
                    " union {[x,y,tv2,tv3] : "
                    "tv2=1 && lb_s <= tv3 && tv3 <= ub_s }");
    EXPECT_EQ(expected->toString(), constraints->toString());
    UFCallTerm* fetched_ufcall = ufcall_map.cloneUFCall(2); // tv2 = ?
    //EXPECT_EQ("f(N, 7 __tv1)", fetched_ufcall->toString() );
    EXPECT_EQ("f(N, 7 __tv1)[0]", fetched_ufcall->toString() );

    delete original_set;
    delete expected;
    delete ufcallptr;
    delete fetched_ufcall;
    delete constraints;
}
<|endoftext|>