<commit_before>/* Begin CVS Header
   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/parameterFitting/CFitProblem.cpp,v $
   $Revision: 1.5 $
   $Name:  $
   $Author: shoops $
   $Date: 2005/10/01 03:02:53 $
   End CVS Header */

#include "copasi.h"

#include "CFitProblem.h"
#include "CFitItem.h"
#include "CFitTask.h"
#include "CExperimentSet.h"
#include "CExperiment.h"

#include "model/CModel.h"
#include "optimization/COptItem.h"
#include "steadystate/CSteadyStateTask.h"
#include "trajectory/CTrajectoryTask.h"
#include "trajectory/CTrajectoryProblem.h"
#include "utilities/CProcessReport.h"

//  Default constructor
CFitProblem::CFitProblem(const CCopasiTask::Type & type,
                         const CCopasiContainer * pParent):
    COptProblem(type, pParent),
    mpExperimentSet(NULL)
{}

// copy constructor
CFitProblem::CFitProblem(const CFitProblem& src,
                         const CCopasiContainer * pParent):
    COptProblem(src, pParent),
    mpExperimentSet(NULL)
{}

// Destructor
CFitProblem::~CFitProblem()
{}

void CFitProblem::initializeParameter()
{
  removeParameter("ObjectiveFunction");
  removeParameter("Maximize");

  assertGroup("Experiment Set");

  elevateChildren();
}

bool CFitProblem::elevateChildren()
{
  mpExperimentSet =
    elevate<CExperimentSet, CCopasiParameterGroup>(getGroup("Experiment Set"));
  if (!mpExperimentSet) return false;

  std::vector<COptItem * >::iterator it = mpOptItems->begin();
  std::vector<COptItem * >::iterator end = mpOptItems->end();

  for (; it != end; ++it)
    if (!((*it) = elevate<CFitItem, COptItem>(*it))) return false;

  it = mpConstraintItems->begin();
  end = mpConstraintItems->end();

  for (; it != end; ++it)
    if (!((*it) = elevate<CFitItem, COptItem>(*it))) return false;

  return true;
}

bool CFitProblem::setModel(CModel * pModel)
{return COptProblem::setModel(pModel);}

bool CFitProblem::setCallBack(CProcessReport * pCallBack)
{return COptProblem::setCallBack(pCallBack);}

bool CFitProblem::initialize()
{
  if (!COptProblem::initialize())
    {
      if (CCopasiMessage::peekLastMessage().getNumber() != MCOptimization + 5)
        return false;
      else
        CCopasiMessage::getLastMessage();
    }

  std::vector< CCopasiContainer * > ContainerList;
  ContainerList.push_back(mpModel);

  CFitTask * pTask = dynamic_cast<CFitTask *>(getObjectParent());
  if (pTask)
    {
      ContainerList.push_back(pTask);
      ContainerList.push_back(mpSteadyState);
      ContainerList.push_back(mpTrajectory);
    }

  if (!mpExperimentSet->compile(ContainerList)) return false;

  // Build a matrix of experiment and experiment local items.
  mExperimentUpdateMethods.resize(mpExperimentSet->size());

  std::vector<COptItem * >::iterator it = mpOptItems->begin();
  std::vector<COptItem * >::iterator end = mpOptItems->end();

  CFitItem * pItem;
  unsigned i, imax;
  for (; it != end; ++it)
    {
      pItem = static_cast<CFitItem *>(*it);
      imax = pItem->getExperimentCount();
      if (imax == 0)
        {
          for (i = 0, imax = mpOptItems->size(); i < imax; i++)
            mExperimentUpdateMethods[i].push_back(pItem->COptItem::getUpdateMethod());
        }
      else
        {
          for (i = 0; i < imax; i++)
            // :TODO: map the experiment key to an experiment index
            // mExperimentUpdateMethods[pItem->getExperiment(i)].push_back(pItem->COptItem::getUpdateMethod();
;
        }
    }

  return true;
}

/**
 * calculate() decides whether the problem is a steady state problem or a
 * trajectory problem based on whether the pointer to that type of problem
 * is null or not.  It then calls the process() method for that type of
 * problem.  Currently process takes ofstream& as a parameter but it will
 * change so that process() takes no parameters.
 */
bool CFitProblem::calculate()
{
  // :TODO: implmement me!

  mCounter += 1;
  bool Continue = true;

  unsigned i, imax = mpExperimentSet->size();
  unsigned j, jmax;
  mCalculateValue = 0.0;

  CTrajectoryProblem * pProblem =
    static_cast<CTrajectoryProblem *>(mpTrajectory->getProblem());

  try
    {
      for (i = 0; i < imax && Continue; i++) // For each experiment
        {
          CExperiment & Exp = *mpExperimentSet->getExperiment(i);

          // :TODO: set the global fit item values.
          // :TODO: set the experiment local fit item values.

          jmax = Exp.getNumRows();

          for (j = 0; j < jmax && Continue; j++) // For each data row;
            {
              // :TODO: set independent data

              switch (Exp.getExperimentType())
                {
                case CCopasiTask::steadyState:
                  Continue = mpSteadyState->process(true);
                  break;

                case CCopasiTask::timeCourse:
                  pProblem->setEndTime(Exp.getTimeData()[j]);
                  Continue = mpTrajectory->process(j ? false : true);
                  break;

                default:
                }

              mCalculateValue += Exp.sumOfSquares(j);
            }
        }
    }

  catch (...)
    {
      mCalculateValue = DBL_MAX;
    }

  if (mpCallBack) return mpCallBack->progress(mhCounter);

  return true;
}

void CFitProblem::print(std::ostream * ostream) const
{*ostream << *this;}

void CFitProblem::printResult(std::ostream * ostream) const
  {COptProblem::printResult(ostream);}

std::ostream &operator<<(std::ostream &os, const CFitProblem & o)
{
  os << "Problem Description:" << std::endl;

  os << "Subtask: " << std::endl;

  if (o.mpSteadyState)
    o.mpSteadyState->getDescription().print(&os);
  else if (o.mpTrajectory)
    o.mpTrajectory->getDescription().print(&os);
  else
    os << "No Subtask specified.";

  os << std::endl;

  os << "List of Optimization Items:" << std::endl;

  std::vector< COptItem * >::const_iterator itItem =
    o.mpOptItems->begin();
  std::vector< COptItem * >::const_iterator endItem =
    o.mpOptItems->end();

  for (; itItem != endItem; ++itItem)
    os << "    " << **itItem << std::endl;

  return os;
}
<commit_msg>Added missing break.<commit_after>/* Begin CVS Header
   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/parameterFitting/CFitProblem.cpp,v $
   $Revision: 1.6 $
   $Name:  $
   $Author: shoops $
   $Date: 2005/10/01 03:04:49 $
   End CVS Header */

#include "copasi.h"

#include "CFitProblem.h"
#include "CFitItem.h"
#include "CFitTask.h"
#include "CExperimentSet.h"
#include "CExperiment.h"

#include "model/CModel.h"
#include "optimization/COptItem.h"
#include "steadystate/CSteadyStateTask.h"
#include "trajectory/CTrajectoryTask.h"
#include "trajectory/CTrajectoryProblem.h"
#include "utilities/CProcessReport.h"

//  Default constructor
CFitProblem::CFitProblem(const CCopasiTask::Type & type,
                         const CCopasiContainer * pParent):
    COptProblem(type, pParent),
    mpExperimentSet(NULL)
{}

// copy constructor
CFitProblem::CFitProblem(const CFitProblem& src,
                         const CCopasiContainer * pParent):
    COptProblem(src, pParent),
    mpExperimentSet(NULL)
{}

// Destructor
CFitProblem::~CFitProblem()
{}

void CFitProblem::initializeParameter()
{
  removeParameter("ObjectiveFunction");
  removeParameter("Maximize");

  assertGroup("Experiment Set");

  elevateChildren();
}

bool CFitProblem::elevateChildren()
{
  mpExperimentSet =
    elevate<CExperimentSet, CCopasiParameterGroup>(getGroup("Experiment Set"));
  if (!mpExperimentSet) return false;

  std::vector<COptItem * >::iterator it = mpOptItems->begin();
  std::vector<COptItem * >::iterator end = mpOptItems->end();

  for (; it != end; ++it)
    if (!((*it) = elevate<CFitItem, COptItem>(*it))) return false;

  it = mpConstraintItems->begin();
  end = mpConstraintItems->end();

  for (; it != end; ++it)
    if (!((*it) = elevate<CFitItem, COptItem>(*it))) return false;

  return true;
}

bool CFitProblem::setModel(CModel * pModel)
{return COptProblem::setModel(pModel);}

bool CFitProblem::setCallBack(CProcessReport * pCallBack)
{return COptProblem::setCallBack(pCallBack);}

bool CFitProblem::initialize()
{
  if (!COptProblem::initialize())
    {
      if (CCopasiMessage::peekLastMessage().getNumber() != MCOptimization + 5)
        return false;
      else
        CCopasiMessage::getLastMessage();
    }

  std::vector< CCopasiContainer * > ContainerList;
  ContainerList.push_back(mpModel);

  CFitTask * pTask = dynamic_cast<CFitTask *>(getObjectParent());
  if (pTask)
    {
      ContainerList.push_back(pTask);
      ContainerList.push_back(mpSteadyState);
      ContainerList.push_back(mpTrajectory);
    }

  if (!mpExperimentSet->compile(ContainerList)) return false;

  // Build a matrix of experiment and experiment local items.
  mExperimentUpdateMethods.resize(mpExperimentSet->size());

  std::vector<COptItem * >::iterator it = mpOptItems->begin();
  std::vector<COptItem * >::iterator end = mpOptItems->end();

  CFitItem * pItem;
  unsigned i, imax;
  for (; it != end; ++it)
    {
      pItem = static_cast<CFitItem *>(*it);
      imax = pItem->getExperimentCount();
      if (imax == 0)
        {
          for (i = 0, imax = mpOptItems->size(); i < imax; i++)
            mExperimentUpdateMethods[i].push_back(pItem->COptItem::getUpdateMethod());
        }
      else
        {
          for (i = 0; i < imax; i++)
            // :TODO: map the experiment key to an experiment index
            // mExperimentUpdateMethods[pItem->getExperiment(i)].push_back(pItem->COptItem::getUpdateMethod();
;
        }
    }

  return true;
}

/**
 * calculate() decides whether the problem is a steady state problem or a
 * trajectory problem based on whether the pointer to that type of problem
 * is null or not.  It then calls the process() method for that type of
 * problem.  Currently process takes ofstream& as a parameter but it will
 * change so that process() takes no parameters.
 */
bool CFitProblem::calculate()
{
  // :TODO: implmement me!

  mCounter += 1;
  bool Continue = true;

  unsigned i, imax = mpExperimentSet->size();
  unsigned j, jmax;
  mCalculateValue = 0.0;

  CTrajectoryProblem * pProblem =
    static_cast<CTrajectoryProblem *>(mpTrajectory->getProblem());

  try
    {
      for (i = 0; i < imax && Continue; i++) // For each experiment
        {
          CExperiment & Exp = *mpExperimentSet->getExperiment(i);

          // :TODO: set the global fit item values.
          // :TODO: set the experiment local fit item values.

          jmax = Exp.getNumRows();

          for (j = 0; j < jmax && Continue; j++) // For each data row;
            {
              // :TODO: set independent data

              switch (Exp.getExperimentType())
                {
                case CCopasiTask::steadyState:
                  Continue = mpSteadyState->process(true);
                  break;

                case CCopasiTask::timeCourse:
                  pProblem->setEndTime(Exp.getTimeData()[j]);
                  Continue = mpTrajectory->process(j ? false : true);
                  break;

                default:
                  break;
                }

              mCalculateValue += Exp.sumOfSquares(j);
            }
        }
    }

  catch (...)
    {
      mCalculateValue = DBL_MAX;
    }

  if (mpCallBack) return mpCallBack->progress(mhCounter);

  return true;
}

void CFitProblem::print(std::ostream * ostream) const
{*ostream << *this;}

void CFitProblem::printResult(std::ostream * ostream) const
  {COptProblem::printResult(ostream);}

std::ostream &operator<<(std::ostream &os, const CFitProblem & o)
{
  os << "Problem Description:" << std::endl;

  os << "Subtask: " << std::endl;

  if (o.mpSteadyState)
    o.mpSteadyState->getDescription().print(&os);
  else if (o.mpTrajectory)
    o.mpTrajectory->getDescription().print(&os);
  else
    os << "No Subtask specified.";

  os << std::endl;

  os << "List of Optimization Items:" << std::endl;

  std::vector< COptItem * >::const_iterator itItem =
    o.mpOptItems->begin();
  std::vector< COptItem * >::const_iterator endItem =
    o.mpOptItems->end();

  for (; itItem != endItem; ++itItem)
    os << "    " << **itItem << std::endl;

  return os;
}
<|endoftext|>


<commit_before>//
//  Created by Bradley Austin Davis on 2016/02/17
//  Copyright 2013-2017 High Fidelity, Inc.
//
//  Distributed under the Apache License, Version 2.0.
//  See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//

#include "storage.hpp"
#include <string>
#include <cstring>
#include <istream>
#include <fstream>
#include <iterator>

#if defined(WIN32)
#include <Windows.h>
#endif

namespace vks { namespace storage {

#if defined(__ANDROID__)
AAssetManager* assetManager = nullptr;
void setAssetManager(AAssetManager* assetManager) {
    vks::storage::assetManager = assetManager;
}
#endif

class ViewStorage : public Storage {
public:
    ViewStorage(const StoragePointer& owner, size_t size, const uint8_t* data)
        : _owner(owner)
        , _size(size)
        , _data(data) {}
    const uint8_t* data() const override { return _data; }
    size_t size() const override { return _size; }
    bool isFast() const override { return _owner->isFast(); }

private:
    const StoragePointer _owner;
    const size_t _size;
    const uint8_t* _data;
};

StoragePointer Storage::createView(size_t viewSize, size_t offset) const {
    auto selfSize = size();
    if (0 == viewSize) {
        viewSize = selfSize;
    }
    if ((viewSize + offset) > selfSize) {
        return StoragePointer();
        //TODO: Disable te exception for now and return an empty storage instead.
        //throw std::runtime_error("Invalid mapping range");
    }
    return std::make_shared<ViewStorage>(shared_from_this(), viewSize, data() + offset);
}

class MemoryStorage : public Storage {
public:
    MemoryStorage(size_t size, const uint8_t* data = nullptr) {
        _data.resize(size);
        if (data) {
            memcpy(_data.data(), data, size);
        }
    }
    const uint8_t* data() const override { return _data.data(); }
    size_t size() const override { return _data.size(); }
    bool isFast() const override { return true; }

private:
    std::vector<uint8_t> _data;
};

class FileStorage : public Storage {
public:
    static StoragePointer create(const std::string& filename, size_t size, const uint8_t* data);
    FileStorage(const std::string& filename);
    ~FileStorage();
    // Prevent copying
    FileStorage(const FileStorage& other) = delete;
    FileStorage& operator=(const FileStorage& other) = delete;

    const uint8_t* data() const override { return _mapped; }
    size_t size() const override { return _size; }
    bool isFast() const override { return false; }

private:
    size_t _size{ 0 };
    uint8_t* _mapped{ nullptr };
#if defined(__ANDROID__)
    AAsset* _asset{ nullptr };
#elif (WIN32)
    HANDLE _file{ INVALID_HANDLE_VALUE };
    HANDLE _mapFile{ INVALID_HANDLE_VALUE };
#else
    std::vector<uint8_t> _data;
#endif
};

FileStorage::FileStorage(const std::string& filename) {
#if defined(__ANDROID__)
    // Load shader from compressed asset
    _asset = AAssetManager_open(assetManager, filename.c_str(), AASSET_MODE_BUFFER);
    assert(_asset);
    _size = AAsset_getLength(_asset);
    assert(_size > 0);
    _mapped = (uint8_t*)(AAsset_getBuffer(_asset));
#elif (WIN32)
    _file = CreateFileA(filename.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
    if (_file == INVALID_HANDLE_VALUE) {
        throw std::runtime_error("Failed to open file");
    }
    {
        DWORD dwFileSizeHigh;
        _size = GetFileSize(_file, &dwFileSizeHigh);
        _size += (((size_t)dwFileSizeHigh) << 32);
    }
    _mapFile = CreateFileMappingA(_file, NULL, PAGE_READONLY, 0, 0, NULL);
    if (_mapFile == INVALID_HANDLE_VALUE) {
        throw std::runtime_error("Failed to create mapping");
    }
    _mapped = (uint8_t*)MapViewOfFile(_mapFile, FILE_MAP_READ, 0, 0, 0);
#else
    // FIXME move to posix memory mapped files
    // open the file:
    std::ifstream file(filename, std::ios::binary);
    // Stop eating new lines in binary mode!!!
    file.unsetf(std::ios::skipws);

    // get its size:
    std::streampos fileSize;

    file.seekg(0, std::ios::end);
    fileSize = file.tellg();
    file.seekg(0, std::ios::beg);

    // reserve capacity
    _data.reserve(fileSize);

    // read the data:
    _data.insert(_data.begin(), std::istream_iterator<uint8_t>(file), std::istream_iterator<uint8_t>());
    _size = _data.size();
    file.close();
#endif
}

FileStorage::~FileStorage() {
#if defined(__ANDROID__)
    AAsset_close(_asset);
#elif (WIN32)
    UnmapViewOfFile(_mapped);
    CloseHandle(_mapFile);
    CloseHandle(_file);
#else
#endif
}

StoragePointer Storage::create(size_t size, uint8_t* data) {
    return std::make_shared<MemoryStorage>(size, data);
}
StoragePointer Storage::readFile(const std::string& filename) {
    return std::make_shared<FileStorage>(filename);
}

}}  // namespace vks::storage
<commit_msg>Fix posix file storage again<commit_after>//
//  Created by Bradley Austin Davis on 2016/02/17
//  Copyright 2013-2017 High Fidelity, Inc.
//
//  Distributed under the Apache License, Version 2.0.
//  See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//

#include "storage.hpp"
#include <string>
#include <cstring>
#include <istream>
#include <fstream>
#include <iterator>

#if defined(WIN32)
#include <Windows.h>
#endif

namespace vks { namespace storage {

#if defined(__ANDROID__)
AAssetManager* assetManager = nullptr;
void setAssetManager(AAssetManager* assetManager) {
    vks::storage::assetManager = assetManager;
}
#endif

class ViewStorage : public Storage {
public:
    ViewStorage(const StoragePointer& owner, size_t size, const uint8_t* data)
        : _owner(owner)
        , _size(size)
        , _data(data) {}
    const uint8_t* data() const override { return _data; }
    size_t size() const override { return _size; }
    bool isFast() const override { return _owner->isFast(); }

private:
    const StoragePointer _owner;
    const size_t _size;
    const uint8_t* _data;
};

StoragePointer Storage::createView(size_t viewSize, size_t offset) const {
    auto selfSize = size();
    if (0 == viewSize) {
        viewSize = selfSize;
    }
    if ((viewSize + offset) > selfSize) {
        return StoragePointer();
        //TODO: Disable te exception for now and return an empty storage instead.
        //throw std::runtime_error("Invalid mapping range");
    }
    return std::make_shared<ViewStorage>(shared_from_this(), viewSize, data() + offset);
}

class MemoryStorage : public Storage {
public:
    MemoryStorage(size_t size, const uint8_t* data = nullptr) {
        _data.resize(size);
        if (data) {
            memcpy(_data.data(), data, size);
        }
    }
    const uint8_t* data() const override { return _data.data(); }
    size_t size() const override { return _data.size(); }
    bool isFast() const override { return true; }

private:
    std::vector<uint8_t> _data;
};

#if defined(__ANDROID__) || defined(WIN32)
#define MAPPED_FILES 1
#else
#define MAPPED_FILES 0
#endif

#if MAPPED_FILES

class FileStorage : public Storage {
public:
    static StoragePointer create(const std::string& filename, size_t size, const uint8_t* data);
    FileStorage(const std::string& filename);
    ~FileStorage();
    // Prevent copying
    FileStorage(const FileStorage& other) = delete;
    FileStorage& operator=(const FileStorage& other) = delete;

    const uint8_t* data() const override { return _mapped; }
    size_t size() const override { return _size; }
    bool isFast() const override { return false; }

private:
    size_t _size{ 0 };
    uint8_t* _mapped{ nullptr };
#if defined(__ANDROID__)
    AAsset* _asset{ nullptr };
#elif (WIN32)
    HANDLE _file{ INVALID_HANDLE_VALUE };
    HANDLE _mapFile{ INVALID_HANDLE_VALUE };
#else
    std::vector<uint8_t> _data;
#endif
};

FileStorage::FileStorage(const std::string& filename) {
#if defined(__ANDROID__)
    // Load shader from compressed asset
    _asset = AAssetManager_open(assetManager, filename.c_str(), AASSET_MODE_BUFFER);
    assert(_asset);
    _size = AAsset_getLength(_asset);
    assert(_size > 0);
    _mapped = (uint8_t*)(AAsset_getBuffer(_asset));
#elif (WIN32)
    _file = CreateFileA(filename.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
    if (_file == INVALID_HANDLE_VALUE) {
        throw std::runtime_error("Failed to open file");
    }
    {
        DWORD dwFileSizeHigh;
        _size = GetFileSize(_file, &dwFileSizeHigh);
        _size += (((size_t)dwFileSizeHigh) << 32);
    }
    _mapFile = CreateFileMappingA(_file, NULL, PAGE_READONLY, 0, 0, NULL);
    if (_mapFile == INVALID_HANDLE_VALUE) {
        throw std::runtime_error("Failed to create mapping");
    }
    _mapped = (uint8_t*)MapViewOfFile(_mapFile, FILE_MAP_READ, 0, 0, 0);
#endif
}

FileStorage::~FileStorage() {
#if defined(__ANDROID__)
    AAsset_close(_asset);
#elif (WIN32)
    UnmapViewOfFile(_mapped);
    CloseHandle(_mapFile);
    CloseHandle(_file);
#endif
}

#endif

StoragePointer Storage::create(size_t size, uint8_t* data) {
    return std::make_shared<MemoryStorage>(size, data);
}
StoragePointer Storage::readFile(const std::string& filename) {
#if MAPPED_FILES
    return std::make_shared<FileStorage>(filename);
#else
    // FIXME move to posix memory mapped files
    // open the file:
    std::ifstream file(filename, std::ios::binary);
    // Stop eating new lines in binary mode!!!
    file.unsetf(std::ios::skipws);

    // get its size:
    std::streampos fileSize;

    file.seekg(0, std::ios::end);
    fileSize = file.tellg();
    file.seekg(0, std::ios::beg);

	std::vector<uint8_t> fileData;
    // reserve capacity
    fileData.reserve(fileSize);
    // read the data:
    fileData.insert(fileData.begin(), std::istream_iterator<uint8_t>(file), std::istream_iterator<uint8_t>());
    file.close();
	return std::make_shared<MemoryStorage>(fileData.size(), fileData.data());
#endif
}

}}  // namespace vks::storage
<|endoftext|>


<commit_before>#ifndef IPOSITION_RECEIVER
#define IPOSITION_RECEIVER

#include <vector>
#include "../matlab/Vector.h"

class IPositionReceiver
{
public:
	/**
	 * Takes the positions of all quadcopters that were updated.
	 * Automatically generates new control information for the quadcopters
	 * and sends it via ROS.
	 *
	 * @param positions The positions of the quadcopters.
	 * @param ids The ids of the quadcopters.
	 * @param updates The amount of image data that went into the position of the quadcopter since the last call of this method.
	 *             Can be ignored for now, but may be useful later.
	 *
	 * Values in the same position in a std::vector belong together. That means, positions.at(i) is the position of the
	 * quadcopter with id ids.at(i) that was generated with updates.at(i) images since the last call of this method.
	 */
	virtual void updatePositions(std::vector<Vector> positions, std::vector<int> ids, std::vector<int> updates) = 0;
};

#endif // IPOSITION_RECEIVER<commit_msg>Added setTrackingArea to IPositionReceiver<commit_after>#ifndef IPOSITION_RECEIVER
#define IPOSITION_RECEIVER

#include <vector>
#include "../matlab/Vector.h"
#include "../matlab/TrackingArea.h"

class IPositionReceiver
{
public:
	/**
	 * Takes the positions of all quadcopters that were updated.
	 * Automatically generates new control information for the quadcopters
	 * and sends it via ROS.
	 *
	 * @param positions The positions of the quadcopters.
	 * @param ids The ids of the quadcopters.
	 * @param updates The amount of image data that went into the position of the quadcopter since the last call of this method.
	 *             Can be ignored for now, but may be useful later.
	 *
	 * Values in the same position in a std::vector belong together. That means, positions.at(i) is the position of the
	 * quadcopter with id ids.at(i) that was generated with updates.at(i) images since the last call of this method.
	 */
	virtual void updatePositions(std::vector<Vector> positions, std::vector<int> ids, std::vector<int> updates) = 0;

	/**
	 * Sets the tracking area to use for controlling the quadcopters.
	 *
	 * @param area The tracking area.
	 */
	virtual void setTrackingArea(TrackingArea area) = 0;
};

#endif // IPOSITION_RECEIVER<|endoftext|>


<commit_before>// Scintilla source code edit control
/** @file LexMSSQL.cxx
 ** Lexer for MSSQL.
 **/
// By Filip Yaghob <fyaghob@gmail.com>

#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>

#include "Platform.h"

#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"

#define KW_MSSQL_STATEMENTS         0
#define KW_MSSQL_DATA_TYPES         1
#define KW_MSSQL_SYSTEM_TABLES      2
#define KW_MSSQL_GLOBAL_VARIABLES   3
#define KW_MSSQL_FUNCTIONS          4
#define KW_MSSQL_STORED_PROCEDURES  5
#define KW_MSSQL_OPERATORS          6

static bool isMSSQLOperator(char ch) {
	if (isascii(ch) && isalnum(ch))
		return false;
	// '.' left out as it is used to make up numbers
	if (ch == '%' || ch == '^' || ch == '&' || ch == '*' ||
        ch == '-' || ch == '+' || ch == '=' || ch == '|' ||
        ch == '<' || ch == '>' || ch == '/' ||
        ch == '!' || ch == '~' || ch == '(' || ch == ')' ||
		ch == ',')
		return true;
	return false;
}

static char classifyWordSQL(unsigned int start,
                            unsigned int end,
                            WordList *keywordlists[],
                            Accessor &styler,
                            unsigned int actualState,
							unsigned int prevState) {
	char s[256];
	bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.');

	WordList &kwStatements          = *keywordlists[KW_MSSQL_STATEMENTS];
    WordList &kwDataTypes           = *keywordlists[KW_MSSQL_DATA_TYPES];
    WordList &kwSystemTables        = *keywordlists[KW_MSSQL_SYSTEM_TABLES];
    WordList &kwGlobalVariables     = *keywordlists[KW_MSSQL_GLOBAL_VARIABLES];
    WordList &kwFunctions           = *keywordlists[KW_MSSQL_FUNCTIONS];
    WordList &kwStoredProcedures    = *keywordlists[KW_MSSQL_STORED_PROCEDURES];
    WordList &kwOperators           = *keywordlists[KW_MSSQL_OPERATORS];

	for (unsigned int i = 0; i < end - start + 1 && i < 128; i++) {
		s[i] = static_cast<char>(tolower(styler[start + i]));
		s[i + 1] = '\0';
	}
	char chAttr = SCE_MSSQL_IDENTIFIER;

	if (actualState == SCE_MSSQL_GLOBAL_VARIABLE) {

        if (kwGlobalVariables.InList(&s[2]))
            chAttr = SCE_MSSQL_GLOBAL_VARIABLE;

	} else if (wordIsNumber) {
		chAttr = SCE_MSSQL_NUMBER;

	} else if (prevState == SCE_MSSQL_DEFAULT_PREF_DATATYPE) {
		// Look first in datatypes
        if (kwDataTypes.InList(s))
            chAttr = SCE_MSSQL_DATATYPE;
		else if (kwOperators.InList(s))
			chAttr = SCE_MSSQL_OPERATOR;
		else if (kwStatements.InList(s))
			chAttr = SCE_MSSQL_STATEMENT;
		else if (kwSystemTables.InList(s))
			chAttr = SCE_MSSQL_SYSTABLE;
		else if (kwFunctions.InList(s))
            chAttr = SCE_MSSQL_FUNCTION;
		else if (kwStoredProcedures.InList(s))
			chAttr = SCE_MSSQL_STORED_PROCEDURE;

	} else {
		if (kwOperators.InList(s))
			chAttr = SCE_MSSQL_OPERATOR;
		else if (kwStatements.InList(s))
			chAttr = SCE_MSSQL_STATEMENT;
		else if (kwSystemTables.InList(s))
			chAttr = SCE_MSSQL_SYSTABLE;
		else if (kwFunctions.InList(s))
			chAttr = SCE_MSSQL_FUNCTION;
		else if (kwStoredProcedures.InList(s))
			chAttr = SCE_MSSQL_STORED_PROCEDURE;
		else if (kwDataTypes.InList(s))
			chAttr = SCE_MSSQL_DATATYPE;
	}

	styler.ColourTo(end, chAttr);

	return chAttr;
}

static void ColouriseMSSQLDoc(unsigned int startPos, int length,
                              int initStyle, WordList *keywordlists[], Accessor &styler) {

	styler.StartAt(startPos);

	bool fold = styler.GetPropertyInt("fold") != 0;
	int lineCurrent = styler.GetLine(startPos);
	int spaceFlags = 0;

	int state = initStyle;
	int prevState = initStyle;
	char chPrev = ' ';
	char chNext = styler[startPos];
	styler.StartSegment(startPos);
	unsigned int lengthDoc = startPos + length;
	for (unsigned int i = startPos; i < lengthDoc; i++) {
		char ch = chNext;
		chNext = styler.SafeGetCharAt(i + 1);

		if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
			int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags);
			int lev = indentCurrent;
			if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
				// Only non whitespace lines can be headers
				int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags);
				if (indentCurrent < (indentNext & ~SC_FOLDLEVELWHITEFLAG)) {
					lev |= SC_FOLDLEVELHEADERFLAG;
				}
			}
			if (fold) {
				styler.SetLevel(lineCurrent, lev);
			}
		}

		if (styler.IsLeadByte(ch)) {
			chNext = styler.SafeGetCharAt(i + 2);
			chPrev = ' ';
			i += 1;
			continue;
		}

		// When the last char isn't part of the state (have to deal with it too)...
		if ( (state == SCE_MSSQL_IDENTIFIER) ||
                    (state == SCE_MSSQL_STORED_PROCEDURE) ||
                    (state == SCE_MSSQL_DATATYPE) ||
                    //~ (state == SCE_MSSQL_COLUMN_NAME) ||
                    (state == SCE_MSSQL_FUNCTION) ||
                    //~ (state == SCE_MSSQL_GLOBAL_VARIABLE) ||
                    (state == SCE_MSSQL_VARIABLE)) {
			if (!iswordchar(ch)) {
				int stateTmp;

                if ((state == SCE_MSSQL_VARIABLE) || (state == SCE_MSSQL_COLUMN_NAME)) {
                    styler.ColourTo(i - 1, state);
					stateTmp = state;
                } else
                    stateTmp = classifyWordSQL(styler.GetStartSegment(), i - 1, keywordlists, styler, state, prevState);

				prevState = state;

				if (stateTmp == SCE_MSSQL_IDENTIFIER || stateTmp == SCE_MSSQL_VARIABLE)
					state = SCE_MSSQL_DEFAULT_PREF_DATATYPE;
				else
					state = SCE_MSSQL_DEFAULT;
			}
		} else if (state == SCE_MSSQL_LINE_COMMENT) {
			if (ch == '\r' || ch == '\n') {
				styler.ColourTo(i - 1, state);
				prevState = state;
				state = SCE_MSSQL_DEFAULT;
			}
		} else if (state == SCE_MSSQL_GLOBAL_VARIABLE) {
			if ((ch != '@') && !iswordchar(ch)) {
				classifyWordSQL(styler.GetStartSegment(), i - 1, keywordlists, styler, state, prevState);
				prevState = state;
				state = SCE_MSSQL_DEFAULT;
			}
		}

		// If is the default or one of the above succeeded
		if (state == SCE_MSSQL_DEFAULT || state == SCE_MSSQL_DEFAULT_PREF_DATATYPE) {
			if (iswordstart(ch)) {
				styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
				prevState = state;
				state = SCE_MSSQL_IDENTIFIER;
			} else if (ch == '/' && chNext == '*') {
				styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
				prevState = state;
				state = SCE_MSSQL_COMMENT;
			} else if (ch == '-' && chNext == '-') {
				styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
				prevState = state;
				state = SCE_MSSQL_LINE_COMMENT;
			} else if (ch == '\'') {
				styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
				prevState = state;
				state = SCE_MSSQL_STRING;
			} else if (ch == '"') {
				styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
				prevState = state;
				state = SCE_MSSQL_COLUMN_NAME;
			} else if (ch == '[') {
				styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
				prevState = state;
				state = SCE_MSSQL_COLUMN_NAME_2;
			} else if (isMSSQLOperator(ch)) {
				styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
				styler.ColourTo(i, SCE_MSSQL_OPERATOR);
                //~ style = SCE_MSSQL_DEFAULT;
				prevState = state;
				state = SCE_MSSQL_DEFAULT;
			} else if (ch == '@') {
                styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
				prevState = state;
                if (chNext == '@') {
                    state = SCE_MSSQL_GLOBAL_VARIABLE;
//                    i += 2;
                } else
                    state = SCE_MSSQL_VARIABLE;
            }

		// When the last char is part of the state...
		} else if (state == SCE_MSSQL_COMMENT) {
				if (ch == '/' && chPrev == '*') {
					if (((i > (styler.GetStartSegment() + 2)) || ((initStyle == SCE_MSSQL_COMMENT) &&
					    (styler.GetStartSegment() == startPos)))) {
						styler.ColourTo(i, state);
						//~ state = SCE_MSSQL_COMMENT;
					prevState = state;
                        state = SCE_MSSQL_DEFAULT;
					}
				}
			} else if (state == SCE_MSSQL_STRING) {
				if (ch == '\'') {
					if ( chNext == '\'' ) {
						i++;
					ch = chNext;
					chNext = styler.SafeGetCharAt(i + 1);
					} else {
						styler.ColourTo(i, state);
					prevState = state;
						state = SCE_MSSQL_DEFAULT;
					//i++;
					}
				//ch = chNext;
				//chNext = styler.SafeGetCharAt(i + 1);
				}
			} else if (state == SCE_MSSQL_COLUMN_NAME) {
				if (ch == '"') {
					if (chNext == '"') {
						i++;
					ch = chNext;
					chNext = styler.SafeGetCharAt(i + 1);
				} else {
                    styler.ColourTo(i, state);
					prevState = state;
					state = SCE_MSSQL_DEFAULT_PREF_DATATYPE;
					//i++;
                }
                }
		} else if (state == SCE_MSSQL_COLUMN_NAME_2) {
			if (ch == ']') {
                styler.ColourTo(i, state);
				prevState = state;
                state = SCE_MSSQL_DEFAULT_PREF_DATATYPE;
                //i++;
			}
		}

		chPrev = ch;
	}
	styler.ColourTo(lengthDoc - 1, state);
}

static void FoldMSSQLDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
	bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
	bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
	unsigned int endPos = startPos + length;
	int visibleChars = 0;
	int lineCurrent = styler.GetLine(startPos);
	int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
	int levelCurrent = levelPrev;
	char chNext = styler[startPos];
	bool inComment = (styler.StyleAt(startPos-1) == SCE_MSSQL_COMMENT);
    char s[10];
	for (unsigned int i = startPos; i < endPos; i++) {
		char ch = chNext;
		chNext = styler.SafeGetCharAt(i + 1);
		int style = styler.StyleAt(i);
		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
        // Comment folding
		if (foldComment) {
			if (!inComment && (style == SCE_MSSQL_COMMENT))
				levelCurrent++;
			else if (inComment && (style != SCE_MSSQL_COMMENT))
				levelCurrent--;
			inComment = (style == SCE_MSSQL_COMMENT);
		}
        if (style == SCE_MSSQL_STATEMENT) {
            // Folding between begin and end
            if (ch == 'b' || ch == 'e') {
                for (unsigned int j = 0; j < 5; j++) {
					if (!iswordchar(styler[i + j])) {
						break;
					}
					s[j] = styler[i + j];
					s[j + 1] = '\0';
                }
				if (strcmp(s, "begin") == 0) {
					levelCurrent++;
				}
				if (strcmp(s, "end") == 0) {
					levelCurrent--;
				}
            }
        }
		if (atEOL) {
			int lev = levelPrev;
			if (visibleChars == 0 && foldCompact)
				lev |= SC_FOLDLEVELWHITEFLAG;
			if ((levelCurrent > levelPrev) && (visibleChars > 0))
				lev |= SC_FOLDLEVELHEADERFLAG;
			if (lev != styler.LevelAt(lineCurrent)) {
				styler.SetLevel(lineCurrent, lev);
			}
			lineCurrent++;
			levelPrev = levelCurrent;
			visibleChars = 0;
		}
		if (!isspacechar(ch))
			visibleChars++;
	}
	// Fill in the real level of the next line, keeping the current flags as they will be filled in later
	int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
	styler.SetLevel(lineCurrent, levelPrev | flagsNext);
}

static const char * const sqlWordListDesc[] = {
	"Statements",
    "Data Types",
    "System tables",
    "Global variables",
    "Functions",
    "System Stored Procedures",
    "Operators",
	0,
};

LexerModule lmMSSQL(SCLEX_MSSQL, ColouriseMSSQLDoc, "mssql", FoldMSSQLDoc, sqlWordListDesc);
<commit_msg>Added license reference to help the picky.<commit_after>// Scintilla source code edit control
/** @file LexMSSQL.cxx
 ** Lexer for MSSQL.
 **/
// By Filip Yaghob <fyaghob@gmail.com>
// The License.txt file describes the conditions under which this software may be distributed.

#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>

#include "Platform.h"

#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"

#define KW_MSSQL_STATEMENTS         0
#define KW_MSSQL_DATA_TYPES         1
#define KW_MSSQL_SYSTEM_TABLES      2
#define KW_MSSQL_GLOBAL_VARIABLES   3
#define KW_MSSQL_FUNCTIONS          4
#define KW_MSSQL_STORED_PROCEDURES  5
#define KW_MSSQL_OPERATORS          6

static bool isMSSQLOperator(char ch) {
	if (isascii(ch) && isalnum(ch))
		return false;
	// '.' left out as it is used to make up numbers
	if (ch == '%' || ch == '^' || ch == '&' || ch == '*' ||
        ch == '-' || ch == '+' || ch == '=' || ch == '|' ||
        ch == '<' || ch == '>' || ch == '/' ||
        ch == '!' || ch == '~' || ch == '(' || ch == ')' ||
		ch == ',')
		return true;
	return false;
}

static char classifyWordSQL(unsigned int start,
                            unsigned int end,
                            WordList *keywordlists[],
                            Accessor &styler,
                            unsigned int actualState,
							unsigned int prevState) {
	char s[256];
	bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.');

	WordList &kwStatements          = *keywordlists[KW_MSSQL_STATEMENTS];
    WordList &kwDataTypes           = *keywordlists[KW_MSSQL_DATA_TYPES];
    WordList &kwSystemTables        = *keywordlists[KW_MSSQL_SYSTEM_TABLES];
    WordList &kwGlobalVariables     = *keywordlists[KW_MSSQL_GLOBAL_VARIABLES];
    WordList &kwFunctions           = *keywordlists[KW_MSSQL_FUNCTIONS];
    WordList &kwStoredProcedures    = *keywordlists[KW_MSSQL_STORED_PROCEDURES];
    WordList &kwOperators           = *keywordlists[KW_MSSQL_OPERATORS];

	for (unsigned int i = 0; i < end - start + 1 && i < 128; i++) {
		s[i] = static_cast<char>(tolower(styler[start + i]));
		s[i + 1] = '\0';
	}
	char chAttr = SCE_MSSQL_IDENTIFIER;

	if (actualState == SCE_MSSQL_GLOBAL_VARIABLE) {

        if (kwGlobalVariables.InList(&s[2]))
            chAttr = SCE_MSSQL_GLOBAL_VARIABLE;

	} else if (wordIsNumber) {
		chAttr = SCE_MSSQL_NUMBER;

	} else if (prevState == SCE_MSSQL_DEFAULT_PREF_DATATYPE) {
		// Look first in datatypes
        if (kwDataTypes.InList(s))
            chAttr = SCE_MSSQL_DATATYPE;
		else if (kwOperators.InList(s))
			chAttr = SCE_MSSQL_OPERATOR;
		else if (kwStatements.InList(s))
			chAttr = SCE_MSSQL_STATEMENT;
		else if (kwSystemTables.InList(s))
			chAttr = SCE_MSSQL_SYSTABLE;
		else if (kwFunctions.InList(s))
            chAttr = SCE_MSSQL_FUNCTION;
		else if (kwStoredProcedures.InList(s))
			chAttr = SCE_MSSQL_STORED_PROCEDURE;

	} else {
		if (kwOperators.InList(s))
			chAttr = SCE_MSSQL_OPERATOR;
		else if (kwStatements.InList(s))
			chAttr = SCE_MSSQL_STATEMENT;
		else if (kwSystemTables.InList(s))
			chAttr = SCE_MSSQL_SYSTABLE;
		else if (kwFunctions.InList(s))
			chAttr = SCE_MSSQL_FUNCTION;
		else if (kwStoredProcedures.InList(s))
			chAttr = SCE_MSSQL_STORED_PROCEDURE;
		else if (kwDataTypes.InList(s))
			chAttr = SCE_MSSQL_DATATYPE;
	}

	styler.ColourTo(end, chAttr);

	return chAttr;
}

static void ColouriseMSSQLDoc(unsigned int startPos, int length,
                              int initStyle, WordList *keywordlists[], Accessor &styler) {

	styler.StartAt(startPos);

	bool fold = styler.GetPropertyInt("fold") != 0;
	int lineCurrent = styler.GetLine(startPos);
	int spaceFlags = 0;

	int state = initStyle;
	int prevState = initStyle;
	char chPrev = ' ';
	char chNext = styler[startPos];
	styler.StartSegment(startPos);
	unsigned int lengthDoc = startPos + length;
	for (unsigned int i = startPos; i < lengthDoc; i++) {
		char ch = chNext;
		chNext = styler.SafeGetCharAt(i + 1);

		if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
			int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags);
			int lev = indentCurrent;
			if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
				// Only non whitespace lines can be headers
				int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags);
				if (indentCurrent < (indentNext & ~SC_FOLDLEVELWHITEFLAG)) {
					lev |= SC_FOLDLEVELHEADERFLAG;
				}
			}
			if (fold) {
				styler.SetLevel(lineCurrent, lev);
			}
		}

		if (styler.IsLeadByte(ch)) {
			chNext = styler.SafeGetCharAt(i + 2);
			chPrev = ' ';
			i += 1;
			continue;
		}

		// When the last char isn't part of the state (have to deal with it too)...
		if ( (state == SCE_MSSQL_IDENTIFIER) ||
                    (state == SCE_MSSQL_STORED_PROCEDURE) ||
                    (state == SCE_MSSQL_DATATYPE) ||
                    //~ (state == SCE_MSSQL_COLUMN_NAME) ||
                    (state == SCE_MSSQL_FUNCTION) ||
                    //~ (state == SCE_MSSQL_GLOBAL_VARIABLE) ||
                    (state == SCE_MSSQL_VARIABLE)) {
			if (!iswordchar(ch)) {
				int stateTmp;

                if ((state == SCE_MSSQL_VARIABLE) || (state == SCE_MSSQL_COLUMN_NAME)) {
                    styler.ColourTo(i - 1, state);
					stateTmp = state;
                } else
                    stateTmp = classifyWordSQL(styler.GetStartSegment(), i - 1, keywordlists, styler, state, prevState);

				prevState = state;

				if (stateTmp == SCE_MSSQL_IDENTIFIER || stateTmp == SCE_MSSQL_VARIABLE)
					state = SCE_MSSQL_DEFAULT_PREF_DATATYPE;
				else
					state = SCE_MSSQL_DEFAULT;
			}
		} else if (state == SCE_MSSQL_LINE_COMMENT) {
			if (ch == '\r' || ch == '\n') {
				styler.ColourTo(i - 1, state);
				prevState = state;
				state = SCE_MSSQL_DEFAULT;
			}
		} else if (state == SCE_MSSQL_GLOBAL_VARIABLE) {
			if ((ch != '@') && !iswordchar(ch)) {
				classifyWordSQL(styler.GetStartSegment(), i - 1, keywordlists, styler, state, prevState);
				prevState = state;
				state = SCE_MSSQL_DEFAULT;
			}
		}

		// If is the default or one of the above succeeded
		if (state == SCE_MSSQL_DEFAULT || state == SCE_MSSQL_DEFAULT_PREF_DATATYPE) {
			if (iswordstart(ch)) {
				styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
				prevState = state;
				state = SCE_MSSQL_IDENTIFIER;
			} else if (ch == '/' && chNext == '*') {
				styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
				prevState = state;
				state = SCE_MSSQL_COMMENT;
			} else if (ch == '-' && chNext == '-') {
				styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
				prevState = state;
				state = SCE_MSSQL_LINE_COMMENT;
			} else if (ch == '\'') {
				styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
				prevState = state;
				state = SCE_MSSQL_STRING;
			} else if (ch == '"') {
				styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
				prevState = state;
				state = SCE_MSSQL_COLUMN_NAME;
			} else if (ch == '[') {
				styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
				prevState = state;
				state = SCE_MSSQL_COLUMN_NAME_2;
			} else if (isMSSQLOperator(ch)) {
				styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
				styler.ColourTo(i, SCE_MSSQL_OPERATOR);
                //~ style = SCE_MSSQL_DEFAULT;
				prevState = state;
				state = SCE_MSSQL_DEFAULT;
			} else if (ch == '@') {
                styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
				prevState = state;
                if (chNext == '@') {
                    state = SCE_MSSQL_GLOBAL_VARIABLE;
//                    i += 2;
                } else
                    state = SCE_MSSQL_VARIABLE;
            }

		// When the last char is part of the state...
		} else if (state == SCE_MSSQL_COMMENT) {
				if (ch == '/' && chPrev == '*') {
					if (((i > (styler.GetStartSegment() + 2)) || ((initStyle == SCE_MSSQL_COMMENT) &&
					    (styler.GetStartSegment() == startPos)))) {
						styler.ColourTo(i, state);
						//~ state = SCE_MSSQL_COMMENT;
					prevState = state;
                        state = SCE_MSSQL_DEFAULT;
					}
				}
			} else if (state == SCE_MSSQL_STRING) {
				if (ch == '\'') {
					if ( chNext == '\'' ) {
						i++;
					ch = chNext;
					chNext = styler.SafeGetCharAt(i + 1);
					} else {
						styler.ColourTo(i, state);
					prevState = state;
						state = SCE_MSSQL_DEFAULT;
					//i++;
					}
				//ch = chNext;
				//chNext = styler.SafeGetCharAt(i + 1);
				}
			} else if (state == SCE_MSSQL_COLUMN_NAME) {
				if (ch == '"') {
					if (chNext == '"') {
						i++;
					ch = chNext;
					chNext = styler.SafeGetCharAt(i + 1);
				} else {
                    styler.ColourTo(i, state);
					prevState = state;
					state = SCE_MSSQL_DEFAULT_PREF_DATATYPE;
					//i++;
                }
                }
		} else if (state == SCE_MSSQL_COLUMN_NAME_2) {
			if (ch == ']') {
                styler.ColourTo(i, state);
				prevState = state;
                state = SCE_MSSQL_DEFAULT_PREF_DATATYPE;
                //i++;
			}
		}

		chPrev = ch;
	}
	styler.ColourTo(lengthDoc - 1, state);
}

static void FoldMSSQLDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
	bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
	bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
	unsigned int endPos = startPos + length;
	int visibleChars = 0;
	int lineCurrent = styler.GetLine(startPos);
	int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
	int levelCurrent = levelPrev;
	char chNext = styler[startPos];
	bool inComment = (styler.StyleAt(startPos-1) == SCE_MSSQL_COMMENT);
    char s[10];
	for (unsigned int i = startPos; i < endPos; i++) {
		char ch = chNext;
		chNext = styler.SafeGetCharAt(i + 1);
		int style = styler.StyleAt(i);
		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
        // Comment folding
		if (foldComment) {
			if (!inComment && (style == SCE_MSSQL_COMMENT))
				levelCurrent++;
			else if (inComment && (style != SCE_MSSQL_COMMENT))
				levelCurrent--;
			inComment = (style == SCE_MSSQL_COMMENT);
		}
        if (style == SCE_MSSQL_STATEMENT) {
            // Folding between begin and end
            if (ch == 'b' || ch == 'e') {
                for (unsigned int j = 0; j < 5; j++) {
					if (!iswordchar(styler[i + j])) {
						break;
					}
					s[j] = styler[i + j];
					s[j + 1] = '\0';
                }
				if (strcmp(s, "begin") == 0) {
					levelCurrent++;
				}
				if (strcmp(s, "end") == 0) {
					levelCurrent--;
				}
            }
        }
		if (atEOL) {
			int lev = levelPrev;
			if (visibleChars == 0 && foldCompact)
				lev |= SC_FOLDLEVELWHITEFLAG;
			if ((levelCurrent > levelPrev) && (visibleChars > 0))
				lev |= SC_FOLDLEVELHEADERFLAG;
			if (lev != styler.LevelAt(lineCurrent)) {
				styler.SetLevel(lineCurrent, lev);
			}
			lineCurrent++;
			levelPrev = levelCurrent;
			visibleChars = 0;
		}
		if (!isspacechar(ch))
			visibleChars++;
	}
	// Fill in the real level of the next line, keeping the current flags as they will be filled in later
	int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
	styler.SetLevel(lineCurrent, levelPrev | flagsNext);
}

static const char * const sqlWordListDesc[] = {
	"Statements",
    "Data Types",
    "System tables",
    "Global variables",
    "Functions",
    "System Stored Procedures",
    "Operators",
	0,
};

LexerModule lmMSSQL(SCLEX_MSSQL, ColouriseMSSQLDoc, "mssql", FoldMSSQLDoc, sqlWordListDesc);
<|endoftext|>


<commit_before>/*
 * Part of HTTPP.
 *
 * Distributed under the 2-clause BSD licence (See LICENCE.TXT file at the
 * project root).
 *
 * Copyright (c) 2014 Thomas Sanchez.  All rights reserved.
 *
 */

#ifndef _HTTPP__DETAIL_CONFIG_HPP_
# define _HTTPP__DETAIL_CONFIG_HPP_

# include <type_traits>

# include <httpp/detail/generated/config.hpp>
# include <httpp/version.hpp>

# ifndef HTTPP_USE_BOOST_PROMISE
#  define HTTPP_USE_BOOST_PROMISE 1
# endif

# if HTTPP_USE_BOOST_PROMISE
#  include <boost/thread/future.hpp>
#  include <boost/exception/all.hpp>
#  define HTTPP_PROMISE_NAMESPACE boost
# else
# include <future>
#  define HTTPP_PROMISE_NAMESPACE std
# endif

# define HTTPP_RAGEL_BACKEND 0
# define HTTPP_STREAM_BACKEND 1

# ifndef HTTPP_PARSER_BACKEND
#  warning "No HTTPP Parser selected, use ragel by default"
#  define HTTPP_PARSER_BACKEND HTTPP_RAGEL_BACKEND
# endif

namespace HTTPP
{

namespace detail
{

template <typename T>
using Promise = HTTPP_PROMISE_NAMESPACE::promise<T>;

template <typename T>
using Future = decltype(std::declval<Promise<T>>().get_future());

# if HTTPP_USE_BOOST_PROMISE

using ExceptionPtr = boost::exception_ptr;

template <typename T>
static inline ExceptionPtr
make_exception_ptr(const T& ex) noexcept(noexcept(boost::copy_exception(ex)))
{
    return boost::copy_exception(ex);
}

static inline ExceptionPtr
current_exception() noexcept(noexcept(boost::current_exception()))
{
    return boost::current_exception();
}

[[noreturn]] static void inline rethrow_exception(const ExceptionPtr& ex)
{
    boost::rethrow_exception(ex);
}

# else

using ExceptionPtr = std::exception_ptr;

template <typename T>
static inline ExceptionPtr make_exception_ptr(const T& ex)
{
    return std::make_exception_ptr(ex);
}

static inline ExceptionPtr
current_exception() noexcept(noexcept(std::current_exception()))
{
    return std::current_exception();
}

[[noreturn]] static void inline rethrow_exception(const ExceptionPtr& ex)
{
    std::rethrow_exception(ex);
}

# endif

} // namespace detail
} // namespace HTTPP

#endif
<commit_msg>Remove code that triggered a boost::promise usage<commit_after>/*
 * Part of HTTPP.
 *
 * Distributed under the 2-clause BSD licence (See LICENCE.TXT file at the
 * project root).
 *
 * Copyright (c) 2014 Thomas Sanchez.  All rights reserved.
 *
 */

#ifndef _HTTPP__DETAIL_CONFIG_HPP_
# define _HTTPP__DETAIL_CONFIG_HPP_

# include <type_traits>

# include <httpp/detail/generated/config.hpp>
# include <httpp/version.hpp>

# if HTTPP_USE_BOOST_PROMISE
#  include <boost/thread/future.hpp>
#  include <boost/exception/all.hpp>
#  define HTTPP_PROMISE_NAMESPACE boost
# else
# include <future>
#  define HTTPP_PROMISE_NAMESPACE std
# endif

# define HTTPP_RAGEL_BACKEND 0
# define HTTPP_STREAM_BACKEND 1

# ifndef HTTPP_PARSER_BACKEND
#  warning "No HTTPP Parser selected, use ragel by default"
#  define HTTPP_PARSER_BACKEND HTTPP_RAGEL_BACKEND
# endif

namespace HTTPP
{

namespace detail
{

template <typename T>
using Promise = HTTPP_PROMISE_NAMESPACE::promise<T>;

template <typename T>
using Future = decltype(std::declval<Promise<T>>().get_future());

# if HTTPP_USE_BOOST_PROMISE

using ExceptionPtr = boost::exception_ptr;

template <typename T>
static inline ExceptionPtr
make_exception_ptr(const T& ex) noexcept(noexcept(boost::copy_exception(ex)))
{
    return boost::copy_exception(ex);
}

static inline ExceptionPtr
current_exception() noexcept(noexcept(boost::current_exception()))
{
    return boost::current_exception();
}

[[noreturn]] static void inline rethrow_exception(const ExceptionPtr& ex)
{
    boost::rethrow_exception(ex);
}

# else

using ExceptionPtr = std::exception_ptr;

template <typename T>
static inline ExceptionPtr make_exception_ptr(const T& ex)
{
    return std::make_exception_ptr(ex);
}

static inline ExceptionPtr
current_exception() noexcept(noexcept(std::current_exception()))
{
    return std::current_exception();
}

[[noreturn]] static void inline rethrow_exception(const ExceptionPtr& ex)
{
    std::rethrow_exception(ex);
}

# endif

} // namespace detail
} // namespace HTTPP

#endif
<|endoftext|>


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

#include "base/string_util.h"
#include "webkit/glue/plugins/test/plugin_client.h"
#include "webkit/glue/plugins/test/plugin_arguments_test.h"
#include "webkit/glue/plugins/test/plugin_delete_plugin_in_stream_test.h"
#include "webkit/glue/plugins/test/plugin_get_javascript_url_test.h"
#include "webkit/glue/plugins/test/plugin_geturl_test.h"
#include "webkit/glue/plugins/test/plugin_javascript_open_popup.h"
#include "webkit/glue/plugins/test/plugin_new_fails_test.h"
#include "webkit/glue/plugins/test/plugin_private_test.h"
#include "webkit/glue/plugins/test/plugin_npobject_lifetime_test.h"
#include "webkit/glue/plugins/test/plugin_npobject_proxy_test.h"
#include "webkit/glue/plugins/test/plugin_window_size_test.h"
#include "webkit/glue/plugins/test/plugin_windowless_test.h"
#include "third_party/npapi/bindings/npapi.h"
#include "third_party/npapi/bindings/npruntime.h"

namespace NPAPIClient {

NPNetscapeFuncs* PluginClient::host_functions_;

NPError PluginClient::GetEntryPoints(NPPluginFuncs* pFuncs) {
  if (pFuncs == NULL)
    return NPERR_INVALID_FUNCTABLE_ERROR;

  if (pFuncs->size < sizeof(NPPluginFuncs))
    return NPERR_INVALID_FUNCTABLE_ERROR;

  pFuncs->version       = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR;
  pFuncs->newp          = NPP_New;
  pFuncs->destroy       = NPP_Destroy;
  pFuncs->setwindow     = NPP_SetWindow;
  pFuncs->newstream     = NPP_NewStream;
  pFuncs->destroystream = NPP_DestroyStream;
  pFuncs->asfile        = NPP_StreamAsFile;
  pFuncs->writeready    = NPP_WriteReady;
  pFuncs->write         = NPP_Write;
  pFuncs->print         = NPP_Print;
  pFuncs->event         = NPP_HandleEvent;
  pFuncs->urlnotify     = NPP_URLNotify;
  pFuncs->getvalue      = NPP_GetValue;
  pFuncs->setvalue      = NPP_SetValue;
  pFuncs->javaClass     = static_cast<JRIGlobalRef>(NPP_GetJavaClass);

  return NPERR_NO_ERROR;
}

NPError PluginClient::Initialize(NPNetscapeFuncs* pFuncs) {
  if (pFuncs == NULL) {
    return NPERR_INVALID_FUNCTABLE_ERROR;
  }

  if (static_cast<unsigned char>((pFuncs->version >> 8) & 0xff) >
      NP_VERSION_MAJOR) {
    return NPERR_INCOMPATIBLE_VERSION_ERROR;
  }

  host_functions_ = pFuncs;

  return NPERR_NO_ERROR;
}

NPError PluginClient::Shutdown() {
  return NPERR_NO_ERROR;
}

} // namespace NPAPIClient

extern "C" {
NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode,
                int16 argc, char* argn[], char* argv[], NPSavedData* saved) {
  if (instance == NULL)
    return NPERR_INVALID_INSTANCE_ERROR;

  // We look at the test name requested via the plugin arguments.  We match
  // that against a given test and try to instantiate it.

  // lookup the name parameter
  std::string test_name;
  for (int name_index = 0; name_index < argc; name_index++)
    if (base::strcasecmp(argn[name_index], "name") == 0) {
      test_name = argv[name_index];
      break;
    }

  if (test_name.empty())
    return NPERR_GENERIC_ERROR;  // no name found

  NPError ret = NPERR_GENERIC_ERROR;
  bool windowless_plugin = false;

  NPAPIClient::PluginTest *new_test = NULL;
  if (test_name == "arguments") {
    new_test = new NPAPIClient::PluginArgumentsTest(instance,
      NPAPIClient::PluginClient::HostFunctions());
  } else if (test_name == "geturl") {
    new_test = new NPAPIClient::PluginGetURLTest(instance,
      NPAPIClient::PluginClient::HostFunctions());
  } else if (test_name == "npobject_proxy") {
    new_test = new NPAPIClient::NPObjectProxyTest(instance,
      NPAPIClient::PluginClient::HostFunctions());
#if defined(OS_WIN)
  // TODO(port): plugin_windowless_test.*.
  } else if (test_name == "execute_script_delete_in_paint" ||
             test_name == "execute_script_delete_in_mouse_move" ||
             test_name == "delete_frame_test") {
    new_test = new NPAPIClient::WindowlessPluginTest(instance,
      NPAPIClient::PluginClient::HostFunctions(), test_name);
    windowless_plugin = true;
#endif
  } else if (test_name == "getjavascripturl") {
    new_test = new NPAPIClient::ExecuteGetJavascriptUrlTest(instance,
      NPAPIClient::PluginClient::HostFunctions());
#if defined(OS_WIN)
  // TODO(port): plugin_window_size_test.*.
  } else if (test_name == "checkwindowrect") {
    new_test = new NPAPIClient::PluginWindowSizeTest(instance,
      NPAPIClient::PluginClient::HostFunctions());
#endif
  } else if (test_name == "self_delete_plugin_stream") {
    new_test = new NPAPIClient::DeletePluginInStreamTest(instance,
      NPAPIClient::PluginClient::HostFunctions());
#if defined(OS_WIN)
  // TODO(port): plugin_npobject_lifetime_test.*.
  } else if (test_name == "npobject_lifetime_test") {
    new_test = new NPAPIClient::NPObjectLifetimeTest(instance,
      NPAPIClient::PluginClient::HostFunctions());
  } else if (test_name == "npobject_lifetime_test_second_instance") {
    new_test = new NPAPIClient::NPObjectLifetimeTestInstance2(instance,
      NPAPIClient::PluginClient::HostFunctions());
  } else if (test_name == "new_fails") {
    new_test = new NPAPIClient::NewFailsTest(instance,
        NPAPIClient::PluginClient::HostFunctions());
  } else if (test_name == "npobject_delete_plugin_in_evaluate") {
    new_test = new NPAPIClient::NPObjectDeletePluginInNPN_Evaluate(instance,
      NPAPIClient::PluginClient::HostFunctions());
#endif
  } else if (test_name ==
             "plugin_javascript_open_popup_with_plugin") {
    new_test = new NPAPIClient::ExecuteJavascriptOpenPopupWithPluginTest(
        instance, NPAPIClient::PluginClient::HostFunctions());
  } else if (test_name == "plugin_popup_with_plugin_target") {
    new_test = new NPAPIClient::ExecuteJavascriptPopupWindowTargetPluginTest(
        instance, NPAPIClient::PluginClient::HostFunctions());
  } else if (test_name == "private") {
    new_test = new NPAPIClient::PrivateTest(instance,
      NPAPIClient::PluginClient::HostFunctions());
  } else {
    // If we don't have a test case for this, create a
    // generic one which basically never fails.
    LOG(WARNING) << "Unknown test name '" << test_name
                 << "'; using default test.";
    new_test = new NPAPIClient::PluginTest(instance,
      NPAPIClient::PluginClient::HostFunctions());
  }

  if (new_test) {
    ret = new_test->New(mode, argc, (const char**)argn,
                       (const char**)argv, saved);
    if ((ret == NPERR_NO_ERROR) && windowless_plugin) {
      NPAPIClient::PluginClient::HostFunctions()->setvalue(
            instance, NPPVpluginWindowBool, NULL);
    }
  }

  return ret;
}

NPError NPP_Destroy(NPP instance, NPSavedData** save) {
  if (instance == NULL)
    return NPERR_INVALID_INSTANCE_ERROR;

  NPAPIClient::PluginTest *plugin =
    (NPAPIClient::PluginTest*)instance->pdata;
  delete plugin;

  // XXXMB - do work here.
  return NPERR_GENERIC_ERROR;
}

NPError NPP_SetWindow(NPP instance, NPWindow* pNPWindow) {
  if (instance == NULL)
    return NPERR_INVALID_INSTANCE_ERROR;

  if (pNPWindow->window == NULL) {
    return NPERR_NO_ERROR;
  }

  NPAPIClient::PluginTest *plugin =
    (NPAPIClient::PluginTest*)instance->pdata;

  return plugin->SetWindow(pNPWindow);
}

NPError NPP_NewStream(NPP instance, NPMIMEType type,
                      NPStream* stream, NPBool seekable, uint16* stype) {
  if (instance == NULL)
    return NPERR_INVALID_INSTANCE_ERROR;

  NPAPIClient::PluginTest *plugin =
    (NPAPIClient::PluginTest*)instance->pdata;

  return plugin->NewStream(type, stream, seekable, stype);
}

int32 NPP_WriteReady(NPP instance, NPStream *stream) {
  if (instance == NULL)
    return NPERR_INVALID_INSTANCE_ERROR;

  NPAPIClient::PluginTest *plugin =
    (NPAPIClient::PluginTest*)instance->pdata;

  return plugin->WriteReady(stream);
}

int32 NPP_Write(NPP instance, NPStream *stream, int32 offset,
                 int32 len, void *buffer) {
  if (instance == NULL)
    return NPERR_INVALID_INSTANCE_ERROR;

  NPAPIClient::PluginTest *plugin =
    (NPAPIClient::PluginTest*)instance->pdata;

  return plugin->Write(stream, offset, len, buffer);
}

NPError NPP_DestroyStream(NPP instance, NPStream *stream, NPError reason) {
  if (instance == NULL)
    return NPERR_INVALID_INSTANCE_ERROR;

  NPAPIClient::PluginTest *plugin =
    (NPAPIClient::PluginTest*)instance->pdata;

  return plugin->DestroyStream(stream, reason);
}

void NPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname) {
  if (instance == NULL)
    return;

  NPAPIClient::PluginTest *plugin =
    (NPAPIClient::PluginTest*)instance->pdata;

  return plugin->StreamAsFile(stream, fname);
}

void NPP_Print(NPP instance, NPPrint* printInfo) {
  if (instance == NULL)
    return;

  // XXXMB - do work here.
}

void NPP_URLNotify(NPP instance, const char* url, NPReason reason,
                   void* notifyData) {
  if (instance == NULL)
    return;

  NPAPIClient::PluginTest *plugin =
    (NPAPIClient::PluginTest*)instance->pdata;

  return plugin->URLNotify(url, reason, notifyData);
}

NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value) {
  if (instance == NULL)
    return NPERR_INVALID_INSTANCE_ERROR;

  // XXXMB - do work here.
  return NPERR_GENERIC_ERROR;
}

NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value) {
  if (instance == NULL)
    return NPERR_INVALID_INSTANCE_ERROR;

  // XXXMB - do work here.
  return NPERR_GENERIC_ERROR;
}

int16 NPP_HandleEvent(NPP instance, void* event) {
  if (instance == NULL)
    return 0;

  NPAPIClient::PluginTest *plugin =
    (NPAPIClient::PluginTest*)instance->pdata;

  return plugin->HandleEvent(event);
}

void* NPP_GetJavaClass(void) {
  // XXXMB - do work here.
  return NULL;
}
} // extern "C"
<commit_msg>Fix build break due to incorrect merge, TBR=awalker<commit_after>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/string_util.h"
#include "webkit/glue/plugins/test/plugin_client.h"
#include "webkit/glue/plugins/test/plugin_arguments_test.h"
#include "webkit/glue/plugins/test/plugin_delete_plugin_in_stream_test.h"
#include "webkit/glue/plugins/test/plugin_get_javascript_url_test.h"
#include "webkit/glue/plugins/test/plugin_geturl_test.h"
#include "webkit/glue/plugins/test/plugin_javascript_open_popup.h"
#include "webkit/glue/plugins/test/plugin_new_fails_test.h"
#include "webkit/glue/plugins/test/plugin_private_test.h"
#include "webkit/glue/plugins/test/plugin_npobject_lifetime_test.h"
#include "webkit/glue/plugins/test/plugin_npobject_proxy_test.h"
#include "webkit/glue/plugins/test/plugin_window_size_test.h"
#include "webkit/glue/plugins/test/plugin_windowless_test.h"
#include "third_party/npapi/bindings/npapi.h"
#include "third_party/npapi/bindings/npruntime.h"

namespace NPAPIClient {

NPNetscapeFuncs* PluginClient::host_functions_;

NPError PluginClient::GetEntryPoints(NPPluginFuncs* pFuncs) {
  if (pFuncs == NULL)
    return NPERR_INVALID_FUNCTABLE_ERROR;

  if (pFuncs->size < sizeof(NPPluginFuncs))
    return NPERR_INVALID_FUNCTABLE_ERROR;

  pFuncs->version       = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR;
  pFuncs->newp          = NPP_New;
  pFuncs->destroy       = NPP_Destroy;
  pFuncs->setwindow     = NPP_SetWindow;
  pFuncs->newstream     = NPP_NewStream;
  pFuncs->destroystream = NPP_DestroyStream;
  pFuncs->asfile        = NPP_StreamAsFile;
  pFuncs->writeready    = NPP_WriteReady;
  pFuncs->write         = NPP_Write;
  pFuncs->print         = NPP_Print;
  pFuncs->event         = NPP_HandleEvent;
  pFuncs->urlnotify     = NPP_URLNotify;
  pFuncs->getvalue      = NPP_GetValue;
  pFuncs->setvalue      = NPP_SetValue;
  pFuncs->javaClass     = reinterpret_cast<JRIGlobalRef>(NPP_GetJavaClass);

  return NPERR_NO_ERROR;
}

NPError PluginClient::Initialize(NPNetscapeFuncs* pFuncs) {
  if (pFuncs == NULL) {
    return NPERR_INVALID_FUNCTABLE_ERROR;
  }

  if (static_cast<unsigned char>((pFuncs->version >> 8) & 0xff) >
      NP_VERSION_MAJOR) {
    return NPERR_INCOMPATIBLE_VERSION_ERROR;
  }

  host_functions_ = pFuncs;

  return NPERR_NO_ERROR;
}

NPError PluginClient::Shutdown() {
  return NPERR_NO_ERROR;
}

} // namespace NPAPIClient

extern "C" {
NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode,
                int16 argc, char* argn[], char* argv[], NPSavedData* saved) {
  if (instance == NULL)
    return NPERR_INVALID_INSTANCE_ERROR;

  // We look at the test name requested via the plugin arguments.  We match
  // that against a given test and try to instantiate it.

  // lookup the name parameter
  std::string test_name;
  for (int name_index = 0; name_index < argc; name_index++)
    if (base::strcasecmp(argn[name_index], "name") == 0) {
      test_name = argv[name_index];
      break;
    }

  if (test_name.empty())
    return NPERR_GENERIC_ERROR;  // no name found

  NPError ret = NPERR_GENERIC_ERROR;
  bool windowless_plugin = false;

  NPAPIClient::PluginTest *new_test = NULL;
  if (test_name == "arguments") {
    new_test = new NPAPIClient::PluginArgumentsTest(instance,
      NPAPIClient::PluginClient::HostFunctions());
  } else if (test_name == "geturl") {
    new_test = new NPAPIClient::PluginGetURLTest(instance,
      NPAPIClient::PluginClient::HostFunctions());
  } else if (test_name == "npobject_proxy") {
    new_test = new NPAPIClient::NPObjectProxyTest(instance,
      NPAPIClient::PluginClient::HostFunctions());
#if defined(OS_WIN)
  // TODO(port): plugin_windowless_test.*.
  } else if (test_name == "execute_script_delete_in_paint" ||
             test_name == "execute_script_delete_in_mouse_move" ||
             test_name == "delete_frame_test") {
    new_test = new NPAPIClient::WindowlessPluginTest(instance,
      NPAPIClient::PluginClient::HostFunctions(), test_name);
    windowless_plugin = true;
#endif
  } else if (test_name == "getjavascripturl") {
    new_test = new NPAPIClient::ExecuteGetJavascriptUrlTest(instance,
      NPAPIClient::PluginClient::HostFunctions());
#if defined(OS_WIN)
  // TODO(port): plugin_window_size_test.*.
  } else if (test_name == "checkwindowrect") {
    new_test = new NPAPIClient::PluginWindowSizeTest(instance,
      NPAPIClient::PluginClient::HostFunctions());
#endif
  } else if (test_name == "self_delete_plugin_stream") {
    new_test = new NPAPIClient::DeletePluginInStreamTest(instance,
      NPAPIClient::PluginClient::HostFunctions());
#if defined(OS_WIN)
  // TODO(port): plugin_npobject_lifetime_test.*.
  } else if (test_name == "npobject_lifetime_test") {
    new_test = new NPAPIClient::NPObjectLifetimeTest(instance,
      NPAPIClient::PluginClient::HostFunctions());
  } else if (test_name == "npobject_lifetime_test_second_instance") {
    new_test = new NPAPIClient::NPObjectLifetimeTestInstance2(instance,
      NPAPIClient::PluginClient::HostFunctions());
  } else if (test_name == "new_fails") {
    new_test = new NPAPIClient::NewFailsTest(instance,
        NPAPIClient::PluginClient::HostFunctions());
  } else if (test_name == "npobject_delete_plugin_in_evaluate") {
    new_test = new NPAPIClient::NPObjectDeletePluginInNPN_Evaluate(instance,
      NPAPIClient::PluginClient::HostFunctions());
#endif
  } else if (test_name ==
             "plugin_javascript_open_popup_with_plugin") {
    new_test = new NPAPIClient::ExecuteJavascriptOpenPopupWithPluginTest(
        instance, NPAPIClient::PluginClient::HostFunctions());
  } else if (test_name == "plugin_popup_with_plugin_target") {
    new_test = new NPAPIClient::ExecuteJavascriptPopupWindowTargetPluginTest(
        instance, NPAPIClient::PluginClient::HostFunctions());
  } else if (test_name == "private") {
    new_test = new NPAPIClient::PrivateTest(instance,
      NPAPIClient::PluginClient::HostFunctions());
  } else {
    // If we don't have a test case for this, create a
    // generic one which basically never fails.
    LOG(WARNING) << "Unknown test name '" << test_name
                 << "'; using default test.";
    new_test = new NPAPIClient::PluginTest(instance,
      NPAPIClient::PluginClient::HostFunctions());
  }

  if (new_test) {
    ret = new_test->New(mode, argc, (const char**)argn,
                       (const char**)argv, saved);
    if ((ret == NPERR_NO_ERROR) && windowless_plugin) {
      NPAPIClient::PluginClient::HostFunctions()->setvalue(
            instance, NPPVpluginWindowBool, NULL);
    }
  }

  return ret;
}

NPError NPP_Destroy(NPP instance, NPSavedData** save) {
  if (instance == NULL)
    return NPERR_INVALID_INSTANCE_ERROR;

  NPAPIClient::PluginTest *plugin =
    (NPAPIClient::PluginTest*)instance->pdata;
  delete plugin;

  // XXXMB - do work here.
  return NPERR_GENERIC_ERROR;
}

NPError NPP_SetWindow(NPP instance, NPWindow* pNPWindow) {
  if (instance == NULL)
    return NPERR_INVALID_INSTANCE_ERROR;

  if (pNPWindow->window == NULL) {
    return NPERR_NO_ERROR;
  }

  NPAPIClient::PluginTest *plugin =
    (NPAPIClient::PluginTest*)instance->pdata;

  return plugin->SetWindow(pNPWindow);
}

NPError NPP_NewStream(NPP instance, NPMIMEType type,
                      NPStream* stream, NPBool seekable, uint16* stype) {
  if (instance == NULL)
    return NPERR_INVALID_INSTANCE_ERROR;

  NPAPIClient::PluginTest *plugin =
    (NPAPIClient::PluginTest*)instance->pdata;

  return plugin->NewStream(type, stream, seekable, stype);
}

int32 NPP_WriteReady(NPP instance, NPStream *stream) {
  if (instance == NULL)
    return NPERR_INVALID_INSTANCE_ERROR;

  NPAPIClient::PluginTest *plugin =
    (NPAPIClient::PluginTest*)instance->pdata;

  return plugin->WriteReady(stream);
}

int32 NPP_Write(NPP instance, NPStream *stream, int32 offset,
                 int32 len, void *buffer) {
  if (instance == NULL)
    return NPERR_INVALID_INSTANCE_ERROR;

  NPAPIClient::PluginTest *plugin =
    (NPAPIClient::PluginTest*)instance->pdata;

  return plugin->Write(stream, offset, len, buffer);
}

NPError NPP_DestroyStream(NPP instance, NPStream *stream, NPError reason) {
  if (instance == NULL)
    return NPERR_INVALID_INSTANCE_ERROR;

  NPAPIClient::PluginTest *plugin =
    (NPAPIClient::PluginTest*)instance->pdata;

  return plugin->DestroyStream(stream, reason);
}

void NPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname) {
  if (instance == NULL)
    return;

  NPAPIClient::PluginTest *plugin =
    (NPAPIClient::PluginTest*)instance->pdata;

  return plugin->StreamAsFile(stream, fname);
}

void NPP_Print(NPP instance, NPPrint* printInfo) {
  if (instance == NULL)
    return;

  // XXXMB - do work here.
}

void NPP_URLNotify(NPP instance, const char* url, NPReason reason,
                   void* notifyData) {
  if (instance == NULL)
    return;

  NPAPIClient::PluginTest *plugin =
    (NPAPIClient::PluginTest*)instance->pdata;

  return plugin->URLNotify(url, reason, notifyData);
}

NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value) {
  if (instance == NULL)
    return NPERR_INVALID_INSTANCE_ERROR;

  // XXXMB - do work here.
  return NPERR_GENERIC_ERROR;
}

NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value) {
  if (instance == NULL)
    return NPERR_INVALID_INSTANCE_ERROR;

  // XXXMB - do work here.
  return NPERR_GENERIC_ERROR;
}

int16 NPP_HandleEvent(NPP instance, void* event) {
  if (instance == NULL)
    return 0;

  NPAPIClient::PluginTest *plugin =
    (NPAPIClient::PluginTest*)instance->pdata;

  return plugin->HandleEvent(event);
}

void* NPP_GetJavaClass(void) {
  // XXXMB - do work here.
  return NULL;
}
} // extern "C"
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing
**
** 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 The Qt Company.  For licensing terms and
** conditions see http://www.qt.io/terms-conditions.  For further information
** use the contact form at http://www.qt.io/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 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file.  Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights.  These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include "giteditor.h"

#include "annotationhighlighter.h"
#include "gitplugin.h"
#include "gitclient.h"
#include "gitsettings.h"
#include "gitsubmiteditorwidget.h"
#include "gitconstants.h"
#include "githighlighters.h"

#include <coreplugin/icore.h>
#include <utils/qtcassert.h>
#include <vcsbase/vcsoutputwindow.h>
#include <texteditor/textdocument.h>

#include <QMenu>

#include <QFileInfo>
#include <QRegExp>
#include <QSet>
#include <QTemporaryFile>
#include <QTextCodec>
#include <QDir>

#include <QTextCursor>
#include <QTextBlock>
#include <QMessageBox>

#define CHANGE_PATTERN "[a-f0-9]{7,40}"

using namespace VcsBase;

namespace Git {
namespace Internal {

GitEditorWidget::GitEditorWidget() :
    m_changeNumberPattern(QLatin1String(CHANGE_PATTERN))
{
    QTC_ASSERT(m_changeNumberPattern.isValid(), return);
    /* Diff format:
        diff --git a/src/plugins/git/giteditor.cpp b/src/plugins/git/giteditor.cpp
        index 40997ff..4e49337 100644
        --- a/src/plugins/git/giteditor.cpp
        +++ b/src/plugins/git/giteditor.cpp
    */
    setDiffFilePattern(QRegExp(QLatin1String("^(?:diff --git a/|index |[+-]{3} (?:/dev/null|[ab]/(.+$)))")));
    setLogEntryPattern(QRegExp(QLatin1String("^commit ([0-9a-f]{8})[0-9a-f]{32}")));
    setAnnotateRevisionTextFormat(tr("&Blame %1"));
    setAnnotatePreviousRevisionTextFormat(tr("Blame &Parent Revision %1"));
}

QSet<QString> GitEditorWidget::annotationChanges() const
{
    QSet<QString> changes;
    const QString txt = toPlainText();
    if (txt.isEmpty())
        return changes;
    // Hunt for first change number in annotation: "<change>:"
    QRegExp r(QLatin1String("^(" CHANGE_PATTERN ") "));
    QTC_ASSERT(r.isValid(), return changes);
    if (r.indexIn(txt) != -1) {
        changes.insert(r.cap(1));
        r.setPattern(QLatin1String("\n(" CHANGE_PATTERN ") "));
        QTC_ASSERT(r.isValid(), return changes);
        int pos = 0;
        while ((pos = r.indexIn(txt, pos)) != -1) {
            pos += r.matchedLength();
            changes.insert(r.cap(1));
        }
    }
    return changes;
}

QString GitEditorWidget::changeUnderCursor(const QTextCursor &c) const
{
    QTextCursor cursor = c;
    // Any number is regarded as change number.
    cursor.select(QTextCursor::WordUnderCursor);
    if (!cursor.hasSelection())
        return QString();
    const QString change = cursor.selectedText();
    if (m_changeNumberPattern.exactMatch(change))
        return change;
    return QString();
}

BaseAnnotationHighlighter *GitEditorWidget::createAnnotationHighlighter(const QSet<QString> &changes) const
{
    return new GitAnnotationHighlighter(changes);
}

/* Remove the date specification from annotation, which is tabular:
\code
8ca887aa (author               YYYY-MM-DD HH:MM:SS <offset>  <line>)<content>
\endcode */

static QString removeAnnotationDate(const QString &b)
{
    if (b.isEmpty())
        return b;

    const QChar space(QLatin1Char(' '));
    const int parenPos = b.indexOf(QLatin1Char(')'));
    if (parenPos == -1)
        return b;
    int datePos = parenPos;

    int i = parenPos;
    while (i >= 0 && b.at(i) != space)
        --i;
    while (i >= 0 && b.at(i) == space)
        --i;
    int spaceCount = 0;
    // i is now on timezone. Go back 3 spaces: That is where the date starts.
    while (i >= 0) {
        if (b.at(i) == space)
            ++spaceCount;
        if (spaceCount == 3) {
            datePos = i;
            break;
        }
        --i;
    }
    if (datePos == 0)
        return b;

    // Copy over the parts that have not changed into a new byte array
    QString result;
    QTC_ASSERT(b.size() >= parenPos, return result);
    int prevPos = 0;
    int pos = b.indexOf(QLatin1Char('\n'), 0) + 1;
    forever {
        QTC_CHECK(prevPos < pos);
        int afterParen = prevPos + parenPos;
        result.append(b.mid(prevPos, datePos));
        result.append(b.mid(afterParen, pos - afterParen));
        prevPos = pos;
        QTC_CHECK(prevPos != 0);
        if (pos == b.size())
            break;

        pos = b.indexOf(QLatin1Char('\n'), pos) + 1;
        if (pos == 0) // indexOf returned -1
            pos = b.size();
    }
    return result;
}

void GitEditorWidget::setPlainText(const QString &text)
{
    QString modText = text;
    GitPlugin *plugin = GitPlugin::instance();
    // If desired, filter out the date from annotation
    switch (contentType())
    {
    case AnnotateOutput: {
        const bool omitAnnotationDate
                = plugin->client()->settings().boolValue(GitSettings::omitAnnotationDateKey);
        if (omitAnnotationDate)
            modText = removeAnnotationDate(text);
        break;
    }
    default:
        break;
    }

    textDocument()->setPlainText(modText);
}

void GitEditorWidget::checkoutChange()
{
    GitPlugin::instance()->client()->stashAndCheckout(
                sourceWorkingDirectory(), m_currentChange);
}

void GitEditorWidget::resetChange(const QByteArray &resetType)
{
    GitPlugin::instance()->client()->reset(
                sourceWorkingDirectory(), QLatin1String("--" + resetType), m_currentChange);
}

void GitEditorWidget::cherryPickChange()
{
    GitPlugin::instance()->client()->synchronousCherryPick(
                sourceWorkingDirectory(), m_currentChange);
}

void GitEditorWidget::revertChange()
{
    GitPlugin::instance()->client()->synchronousRevert(
                sourceWorkingDirectory(), m_currentChange);
}

void GitEditorWidget::logChange()
{
    GitPlugin::instance()->client()->log(
                sourceWorkingDirectory(), QString(), false, QStringList(m_currentChange));
}

void GitEditorWidget::applyDiffChunk(const DiffChunk& chunk, bool revert)
{
    QTemporaryFile patchFile;
    if (!patchFile.open())
        return;

    const QString baseDir = workingDirectory();
    patchFile.write(chunk.header);
    patchFile.write(chunk.chunk);
    patchFile.close();

    GitClient *client = GitPlugin::instance()->client();
    QStringList args = QStringList() << QLatin1String("--cached");
    if (revert)
        args << QLatin1String("--reverse");
    QString errorMessage;
    if (client->synchronousApplyPatch(baseDir, patchFile.fileName(), &errorMessage, args)) {
        if (errorMessage.isEmpty())
            VcsOutputWindow::append(tr("Chunk successfully staged"));
        else
            VcsOutputWindow::append(errorMessage);
        if (revert)
            emit diffChunkReverted(chunk);
        else
            emit diffChunkApplied(chunk);
    } else {
        VcsOutputWindow::appendError(errorMessage);
    }
}

void GitEditorWidget::init()
{
    VcsBaseEditorWidget::init();
    Core::Id editorId = textDocument()->id();
    if (editorId == Git::Constants::GIT_COMMIT_TEXT_EDITOR_ID)
        textDocument()->setSyntaxHighlighter(new GitSubmitHighlighter);
    else if (editorId == Git::Constants::GIT_REBASE_EDITOR_ID)
        textDocument()->setSyntaxHighlighter(new GitRebaseHighlighter);
}

void GitEditorWidget::addDiffActions(QMenu *menu, const DiffChunk &chunk)
{
    menu->addSeparator();

    QAction *stageAction = menu->addAction(tr("Stage Chunk..."));
    connect(stageAction, &QAction::triggered, this, [this, chunk] {
        applyDiffChunk(chunk, false);
    });

    QAction *unstageAction = menu->addAction(tr("Unstage Chunk..."));
    connect(unstageAction, &QAction::triggered, this, [this, chunk] {
        applyDiffChunk(chunk, true);
    });
}

void GitEditorWidget::aboutToOpen(const QString &fileName, const QString &realFileName)
{
    Q_UNUSED(realFileName)
    Core::Id editorId = textDocument()->id();
    if (editorId == Git::Constants::GIT_COMMIT_TEXT_EDITOR_ID
            || editorId == Git::Constants::GIT_REBASE_EDITOR_ID) {
        QFileInfo fi(fileName);
        const QString gitPath = fi.absolutePath();
        setSource(gitPath);
        textDocument()->setCodec(
                    GitPlugin::instance()->client()->encoding(gitPath, "i18n.commitEncoding"));
    }
}

QString GitEditorWidget::decorateVersion(const QString &revision) const
{
    const QFileInfo fi(source());
    const QString workingDirectory = fi.absolutePath();

    // Format verbose, SHA1 being first token
    return GitPlugin::instance()->client()->synchronousShortDescription(workingDirectory, revision);
}

QStringList GitEditorWidget::annotationPreviousVersions(const QString &revision) const
{
    QStringList revisions;
    QString errorMessage;
    GitClient *client = GitPlugin::instance()->client();
    const QFileInfo fi(source());
    const QString workingDirectory = fi.absolutePath();
    // Get the SHA1's of the file.
    if (!client->synchronousParentRevisions(workingDirectory, QStringList(fi.fileName()),
                                            revision, &revisions, &errorMessage)) {
        VcsOutputWindow::appendSilently(errorMessage);
        return QStringList();
    }
    return revisions;
}

bool GitEditorWidget::isValidRevision(const QString &revision) const
{
    return GitPlugin::instance()->client()->isValidRevision(revision);
}

void GitEditorWidget::addChangeActions(QMenu *menu, const QString &change)
{
    m_currentChange = change;
    if (contentType() != OtherContent) {
        menu->addAction(tr("Cherr&y-Pick Change %1").arg(change), this, SLOT(cherryPickChange()));
        menu->addAction(tr("Re&vert Change %1").arg(change), this, SLOT(revertChange()));
        menu->addAction(tr("C&heckout Change %1").arg(change), this, SLOT(checkoutChange()));
        menu->addAction(tr("&Log for Change %1").arg(change), this, SLOT(logChange()));
        QMenu *resetMenu = new QMenu(tr("&Reset to Change %1").arg(change), menu);
        connect(resetMenu->addAction(tr("&Hard")), &QAction::triggered,
                this, [this]() { resetChange("hard"); });
        connect(resetMenu->addAction(tr("&Mixed")), &QAction::triggered,
                this, [this]() { resetChange("mixed"); });
        connect(resetMenu->addAction(tr("&Soft")), &QAction::triggered,
                this, [this]() { resetChange("soft"); });
        menu->addMenu(resetMenu);
    }
}

QString GitEditorWidget::revisionSubject(const QTextBlock &inBlock) const
{
    for (QTextBlock block = inBlock.next(); block.isValid(); block = block.next()) {
        const QString line = block.text().trimmed();
        if (line.isEmpty()) {
            block = block.next();
            return block.text().trimmed();
        }
    }
    return QString();
}

bool GitEditorWidget::supportChangeLinks() const
{
    return VcsBaseEditorWidget::supportChangeLinks()
            || (textDocument()->id() == Git::Constants::GIT_COMMIT_TEXT_EDITOR_ID)
            || (textDocument()->id() == Git::Constants::GIT_REBASE_EDITOR_ID);
}

QString GitEditorWidget::fileNameForLine(int line) const
{
    // 7971b6e7 share/qtcreator/dumper/dumper.py   (hjk
    QTextBlock block = document()->findBlockByLineNumber(line - 1);
    QTC_ASSERT(block.isValid(), return source());
    static QRegExp renameExp(QLatin1String("^" CHANGE_PATTERN "\\s+([^(]+)"));
    if (renameExp.indexIn(block.text()) != -1) {
        const QString fileName = renameExp.cap(1).trimmed();
        if (!fileName.isEmpty())
            return fileName;
    }
    return source();
}

QString GitEditorWidget::sourceWorkingDirectory() const
{
    const QFileInfo fi(source());
    return fi.isDir() ? fi.absoluteFilePath() : fi.absolutePath();
}

} // namespace Internal
} // namespace Git
<commit_msg>Git: Strip line numbers from blame output<commit_after>/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing
**
** 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 The Qt Company.  For licensing terms and
** conditions see http://www.qt.io/terms-conditions.  For further information
** use the contact form at http://www.qt.io/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 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file.  Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, The Qt Company gives you certain additional
** rights.  These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include "giteditor.h"

#include "annotationhighlighter.h"
#include "gitplugin.h"
#include "gitclient.h"
#include "gitsettings.h"
#include "gitsubmiteditorwidget.h"
#include "gitconstants.h"
#include "githighlighters.h"

#include <coreplugin/icore.h>
#include <utils/qtcassert.h>
#include <vcsbase/vcsoutputwindow.h>
#include <texteditor/textdocument.h>

#include <QMenu>

#include <QFileInfo>
#include <QRegExp>
#include <QSet>
#include <QTemporaryFile>
#include <QTextCodec>
#include <QDir>

#include <QTextCursor>
#include <QTextBlock>
#include <QMessageBox>

#define CHANGE_PATTERN "[a-f0-9]{7,40}"

using namespace VcsBase;

namespace Git {
namespace Internal {

GitEditorWidget::GitEditorWidget() :
    m_changeNumberPattern(QLatin1String(CHANGE_PATTERN))
{
    QTC_ASSERT(m_changeNumberPattern.isValid(), return);
    /* Diff format:
        diff --git a/src/plugins/git/giteditor.cpp b/src/plugins/git/giteditor.cpp
        index 40997ff..4e49337 100644
        --- a/src/plugins/git/giteditor.cpp
        +++ b/src/plugins/git/giteditor.cpp
    */
    setDiffFilePattern(QRegExp(QLatin1String("^(?:diff --git a/|index |[+-]{3} (?:/dev/null|[ab]/(.+$)))")));
    setLogEntryPattern(QRegExp(QLatin1String("^commit ([0-9a-f]{8})[0-9a-f]{32}")));
    setAnnotateRevisionTextFormat(tr("&Blame %1"));
    setAnnotatePreviousRevisionTextFormat(tr("Blame &Parent Revision %1"));
}

QSet<QString> GitEditorWidget::annotationChanges() const
{
    QSet<QString> changes;
    const QString txt = toPlainText();
    if (txt.isEmpty())
        return changes;
    // Hunt for first change number in annotation: "<change>:"
    QRegExp r(QLatin1String("^(" CHANGE_PATTERN ") "));
    QTC_ASSERT(r.isValid(), return changes);
    if (r.indexIn(txt) != -1) {
        changes.insert(r.cap(1));
        r.setPattern(QLatin1String("\n(" CHANGE_PATTERN ") "));
        QTC_ASSERT(r.isValid(), return changes);
        int pos = 0;
        while ((pos = r.indexIn(txt, pos)) != -1) {
            pos += r.matchedLength();
            changes.insert(r.cap(1));
        }
    }
    return changes;
}

QString GitEditorWidget::changeUnderCursor(const QTextCursor &c) const
{
    QTextCursor cursor = c;
    // Any number is regarded as change number.
    cursor.select(QTextCursor::WordUnderCursor);
    if (!cursor.hasSelection())
        return QString();
    const QString change = cursor.selectedText();
    if (m_changeNumberPattern.exactMatch(change))
        return change;
    return QString();
}

BaseAnnotationHighlighter *GitEditorWidget::createAnnotationHighlighter(const QSet<QString> &changes) const
{
    return new GitAnnotationHighlighter(changes);
}

/* Remove the date specification from annotation, which is tabular:
\code
8ca887aa (author               YYYY-MM-DD HH:MM:SS <offset>  <line>)<content>
\endcode */

static QString sanitizeBlameOutput(const QString &b)
{
    if (b.isEmpty())
        return b;

    const bool omitDate = GitPlugin::instance()->client()->settings().boolValue(
                GitSettings::omitAnnotationDateKey);
    const QChar space(QLatin1Char(' '));
    const int parenPos = b.indexOf(QLatin1Char(')'));
    if (parenPos == -1)
        return b;

    int i = parenPos;
    while (i >= 0 && b.at(i) != space)
        --i;
    while (i >= 0 && b.at(i) == space)
        --i;
    int stripPos = i + 1;
    if (omitDate) {
        int spaceCount = 0;
        // i is now on timezone. Go back 3 spaces: That is where the date starts.
        while (i >= 0) {
            if (b.at(i) == space)
                ++spaceCount;
            if (spaceCount == 3) {
                stripPos = i;
                break;
            }
            --i;
        }
    }

    // Copy over the parts that have not changed into a new byte array
    QString result;
    int prevPos = 0;
    int pos = b.indexOf(QLatin1Char('\n'), 0) + 1;
    forever {
        QTC_CHECK(prevPos < pos);
        int afterParen = prevPos + parenPos;
        result.append(b.mid(prevPos, stripPos));
        result.append(b.mid(afterParen, pos - afterParen));
        prevPos = pos;
        QTC_CHECK(prevPos != 0);
        if (pos == b.size())
            break;

        pos = b.indexOf(QLatin1Char('\n'), pos) + 1;
        if (pos == 0) // indexOf returned -1
            pos = b.size();
    }
    return result;
}

void GitEditorWidget::setPlainText(const QString &text)
{
    QString modText = text;
    // If desired, filter out the date from annotation
    switch (contentType())
    {
    case AnnotateOutput:
        modText = sanitizeBlameOutput(text);
        break;
    default:
        break;
    }

    textDocument()->setPlainText(modText);
}

void GitEditorWidget::checkoutChange()
{
    GitPlugin::instance()->client()->stashAndCheckout(
                sourceWorkingDirectory(), m_currentChange);
}

void GitEditorWidget::resetChange(const QByteArray &resetType)
{
    GitPlugin::instance()->client()->reset(
                sourceWorkingDirectory(), QLatin1String("--" + resetType), m_currentChange);
}

void GitEditorWidget::cherryPickChange()
{
    GitPlugin::instance()->client()->synchronousCherryPick(
                sourceWorkingDirectory(), m_currentChange);
}

void GitEditorWidget::revertChange()
{
    GitPlugin::instance()->client()->synchronousRevert(
                sourceWorkingDirectory(), m_currentChange);
}

void GitEditorWidget::logChange()
{
    GitPlugin::instance()->client()->log(
                sourceWorkingDirectory(), QString(), false, QStringList(m_currentChange));
}

void GitEditorWidget::applyDiffChunk(const DiffChunk& chunk, bool revert)
{
    QTemporaryFile patchFile;
    if (!patchFile.open())
        return;

    const QString baseDir = workingDirectory();
    patchFile.write(chunk.header);
    patchFile.write(chunk.chunk);
    patchFile.close();

    GitClient *client = GitPlugin::instance()->client();
    QStringList args = QStringList() << QLatin1String("--cached");
    if (revert)
        args << QLatin1String("--reverse");
    QString errorMessage;
    if (client->synchronousApplyPatch(baseDir, patchFile.fileName(), &errorMessage, args)) {
        if (errorMessage.isEmpty())
            VcsOutputWindow::append(tr("Chunk successfully staged"));
        else
            VcsOutputWindow::append(errorMessage);
        if (revert)
            emit diffChunkReverted(chunk);
        else
            emit diffChunkApplied(chunk);
    } else {
        VcsOutputWindow::appendError(errorMessage);
    }
}

void GitEditorWidget::init()
{
    VcsBaseEditorWidget::init();
    Core::Id editorId = textDocument()->id();
    if (editorId == Git::Constants::GIT_COMMIT_TEXT_EDITOR_ID)
        textDocument()->setSyntaxHighlighter(new GitSubmitHighlighter);
    else if (editorId == Git::Constants::GIT_REBASE_EDITOR_ID)
        textDocument()->setSyntaxHighlighter(new GitRebaseHighlighter);
}

void GitEditorWidget::addDiffActions(QMenu *menu, const DiffChunk &chunk)
{
    menu->addSeparator();

    QAction *stageAction = menu->addAction(tr("Stage Chunk..."));
    connect(stageAction, &QAction::triggered, this, [this, chunk] {
        applyDiffChunk(chunk, false);
    });

    QAction *unstageAction = menu->addAction(tr("Unstage Chunk..."));
    connect(unstageAction, &QAction::triggered, this, [this, chunk] {
        applyDiffChunk(chunk, true);
    });
}

void GitEditorWidget::aboutToOpen(const QString &fileName, const QString &realFileName)
{
    Q_UNUSED(realFileName)
    Core::Id editorId = textDocument()->id();
    if (editorId == Git::Constants::GIT_COMMIT_TEXT_EDITOR_ID
            || editorId == Git::Constants::GIT_REBASE_EDITOR_ID) {
        QFileInfo fi(fileName);
        const QString gitPath = fi.absolutePath();
        setSource(gitPath);
        textDocument()->setCodec(
                    GitPlugin::instance()->client()->encoding(gitPath, "i18n.commitEncoding"));
    }
}

QString GitEditorWidget::decorateVersion(const QString &revision) const
{
    const QFileInfo fi(source());
    const QString workingDirectory = fi.absolutePath();

    // Format verbose, SHA1 being first token
    return GitPlugin::instance()->client()->synchronousShortDescription(workingDirectory, revision);
}

QStringList GitEditorWidget::annotationPreviousVersions(const QString &revision) const
{
    QStringList revisions;
    QString errorMessage;
    GitClient *client = GitPlugin::instance()->client();
    const QFileInfo fi(source());
    const QString workingDirectory = fi.absolutePath();
    // Get the SHA1's of the file.
    if (!client->synchronousParentRevisions(workingDirectory, QStringList(fi.fileName()),
                                            revision, &revisions, &errorMessage)) {
        VcsOutputWindow::appendSilently(errorMessage);
        return QStringList();
    }
    return revisions;
}

bool GitEditorWidget::isValidRevision(const QString &revision) const
{
    return GitPlugin::instance()->client()->isValidRevision(revision);
}

void GitEditorWidget::addChangeActions(QMenu *menu, const QString &change)
{
    m_currentChange = change;
    if (contentType() != OtherContent) {
        menu->addAction(tr("Cherr&y-Pick Change %1").arg(change), this, SLOT(cherryPickChange()));
        menu->addAction(tr("Re&vert Change %1").arg(change), this, SLOT(revertChange()));
        menu->addAction(tr("C&heckout Change %1").arg(change), this, SLOT(checkoutChange()));
        menu->addAction(tr("&Log for Change %1").arg(change), this, SLOT(logChange()));
        QMenu *resetMenu = new QMenu(tr("&Reset to Change %1").arg(change), menu);
        connect(resetMenu->addAction(tr("&Hard")), &QAction::triggered,
                this, [this]() { resetChange("hard"); });
        connect(resetMenu->addAction(tr("&Mixed")), &QAction::triggered,
                this, [this]() { resetChange("mixed"); });
        connect(resetMenu->addAction(tr("&Soft")), &QAction::triggered,
                this, [this]() { resetChange("soft"); });
        menu->addMenu(resetMenu);
    }
}

QString GitEditorWidget::revisionSubject(const QTextBlock &inBlock) const
{
    for (QTextBlock block = inBlock.next(); block.isValid(); block = block.next()) {
        const QString line = block.text().trimmed();
        if (line.isEmpty()) {
            block = block.next();
            return block.text().trimmed();
        }
    }
    return QString();
}

bool GitEditorWidget::supportChangeLinks() const
{
    return VcsBaseEditorWidget::supportChangeLinks()
            || (textDocument()->id() == Git::Constants::GIT_COMMIT_TEXT_EDITOR_ID)
            || (textDocument()->id() == Git::Constants::GIT_REBASE_EDITOR_ID);
}

QString GitEditorWidget::fileNameForLine(int line) const
{
    // 7971b6e7 share/qtcreator/dumper/dumper.py   (hjk
    QTextBlock block = document()->findBlockByLineNumber(line - 1);
    QTC_ASSERT(block.isValid(), return source());
    static QRegExp renameExp(QLatin1String("^" CHANGE_PATTERN "\\s+([^(]+)"));
    if (renameExp.indexIn(block.text()) != -1) {
        const QString fileName = renameExp.cap(1).trimmed();
        if (!fileName.isEmpty())
            return fileName;
    }
    return source();
}

QString GitEditorWidget::sourceWorkingDirectory() const
{
    const QFileInfo fi(source());
    return fi.isDir() ? fi.absoluteFilePath() : fi.absolutePath();
}

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