<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: DrawModelBroadcaster.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: kz $ $Date: 2006-07-21 13:08:05 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"

#ifndef _SC_DRAWMODELBROADCASTER_HXX
#include "DrawModelBroadcaster.hxx"
#endif

#ifndef _SVDMODEL_HXX
#include <svx/svdmodel.hxx>
#endif
#ifndef SVX_UNOMOD_HXX
#include <svx/unomod.hxx>
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif

using namespace ::com::sun::star;

ScDrawModelBroadcaster::ScDrawModelBroadcaster( SdrModel *pDrawModel ) :
    maEventListeners( maListenerMutex ),
    mpDrawModel( pDrawModel )
{
    if (mpDrawModel)
        StartListening( *mpDrawModel );
}

ScDrawModelBroadcaster::~ScDrawModelBroadcaster()
{
    if (mpDrawModel)
        EndListening( *mpDrawModel );
}

void SAL_CALL ScDrawModelBroadcaster::addEventListener( const uno::Reference< document::XEventListener >& xListener )
    throw (uno::RuntimeException)
{
    maEventListeners.addInterface( xListener );
}

void SAL_CALL ScDrawModelBroadcaster::removeEventListener( const uno::Reference< document::XEventListener >& xListener )
    throw (uno::RuntimeException)
{
    maEventListeners.removeInterface( xListener );
}

void ScDrawModelBroadcaster::Notify( SfxBroadcaster& rBC,
        const SfxHint& rHint )
{
    const SdrHint *pSdrHint = PTR_CAST( SdrHint, &rHint );
    if( !pSdrHint )
        return;

    document::EventObject aEvent;
    if( !SvxUnoDrawMSFactory::createEvent( mpDrawModel, pSdrHint, aEvent ) )
        return;

    ::cppu::OInterfaceIteratorHelper aIter( maEventListeners );
    while( aIter.hasMoreElements() )
    {
        uno::Reference < document::XEventListener > xListener( aIter.next(), uno::UNO_QUERY );
        try
        {
            xListener->notifyEvent( aEvent );
        }
        catch( uno::RuntimeException& r )
        {
#if OSL_DEBUG_LEVEL > 1
            ByteString aError( "Runtime exception caught while notifying shape.:\n" );
            aError += ByteString( String( r.Message), RTL_TEXTENCODING_ASCII_US );
            DBG_ERROR( aError.GetBuffer() );
#endif
        }
    }
}
<commit_msg>INTEGRATION: CWS calcwarnings (1.5.110); FILE MERGED 2006/12/01 08:53:20 nn 1.5.110.1: #i69284# warning-free: ui, wntmsci10<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: DrawModelBroadcaster.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: vg $ $Date: 2007-02-27 12:57:11 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"

#ifndef _SC_DRAWMODELBROADCASTER_HXX
#include "DrawModelBroadcaster.hxx"
#endif

#ifndef _SVDMODEL_HXX
#include <svx/svdmodel.hxx>
#endif
#ifndef SVX_UNOMOD_HXX
#include <svx/unomod.hxx>
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif

using namespace ::com::sun::star;

ScDrawModelBroadcaster::ScDrawModelBroadcaster( SdrModel *pDrawModel ) :
    maEventListeners( maListenerMutex ),
    mpDrawModel( pDrawModel )
{
    if (mpDrawModel)
        StartListening( *mpDrawModel );
}

ScDrawModelBroadcaster::~ScDrawModelBroadcaster()
{
    if (mpDrawModel)
        EndListening( *mpDrawModel );
}

void SAL_CALL ScDrawModelBroadcaster::addEventListener( const uno::Reference< document::XEventListener >& xListener )
    throw (uno::RuntimeException)
{
    maEventListeners.addInterface( xListener );
}

void SAL_CALL ScDrawModelBroadcaster::removeEventListener( const uno::Reference< document::XEventListener >& xListener )
    throw (uno::RuntimeException)
{
    maEventListeners.removeInterface( xListener );
}

void ScDrawModelBroadcaster::Notify( SfxBroadcaster&,
        const SfxHint& rHint )
{
    const SdrHint *pSdrHint = PTR_CAST( SdrHint, &rHint );
    if( !pSdrHint )
        return;

    document::EventObject aEvent;
    if( !SvxUnoDrawMSFactory::createEvent( mpDrawModel, pSdrHint, aEvent ) )
        return;

    ::cppu::OInterfaceIteratorHelper aIter( maEventListeners );
    while( aIter.hasMoreElements() )
    {
        uno::Reference < document::XEventListener > xListener( aIter.next(), uno::UNO_QUERY );
        try
        {
            xListener->notifyEvent( aEvent );
        }
        catch( uno::RuntimeException& r )
        {
            (void) r;
#if OSL_DEBUG_LEVEL > 1
            ByteString aError( "Runtime exception caught while notifying shape.:\n" );
            aError += ByteString( String( r.Message), RTL_TEXTENCODING_ASCII_US );
            DBG_ERROR( aError.GetBuffer() );
#endif
        }
    }
}
<|endoftext|>


<commit_before>#include "gameObject.h"
#include "game.h"
#include "resources.h"
#include "main.h"

GameObject::~GameObject()
{

}

void GameObject::Init(float x, float y, CIw2DImage* image)
{
	m_X = x;
	m_Y = y;

	SetImage(image);
}

void GameObject::Init(float x, float y, CAtlas* atlas)
{
	m_X = x;
	m_Y = y;

	SetAtlas(atlas);
}

void GameObject::UpdatePosition(float x, float y)
{
	m_X = x;
	m_Y = y;
}

void GameObject::setId(int id)
{
	objId = id;
}

void GameObject::setGridCoords(int x, int y)
{
	gridX = x;
	gridY = y;

	IwTrace(APP, ("i have been set to %d, %d", gridX, gridY));
}

std::pair<int, int> GameObject::getCoords()
{
	std::pair<int, int> coords(gridX, gridY);

	return coords;
}<commit_msg>Fixed by adding animation duration and repeat<commit_after>#include "gameObject.h"
#include "game.h"
#include "resources.h"
#include "main.h"

GameObject::~GameObject()
{

}

void GameObject::Init(float x, float y, CIw2DImage* image)
{
	m_X = x;
	m_Y = y;

	SetImage(image);
}

void GameObject::Init(float x, float y, CAtlas* atlas)
{
	m_X = x;
	m_Y = y;

	SetAtlas(atlas);
	SetAnimDuration(2);
	SetAnimRepeat(1);
}

void GameObject::UpdatePosition(float x, float y)
{
	m_X = x;
	m_Y = y;
}

void GameObject::setId(int id)
{
	objId = id;
}

void GameObject::setGridCoords(int x, int y)
{
	gridX = x;
	gridY = y;

	IwTrace(APP, ("i have been set to %d, %d", gridX, gridY));
}

std::pair<int, int> GameObject::getCoords()
{
	std::pair<int, int> coords(gridX, gridY);

	return coords;
}<|endoftext|>


<commit_before>/*  This file is part of the KDE project
    Copyright (C) 2006-2007 Matthias Kretz <kretz@kde.org>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License version 2 as published by the Free Software Foundation.

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

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

*/

#include "audiooutput.h"
#include <QtCore/QVector>

//#include <phonon/config-alsa.h>

#ifdef HAVE_SYS_SOUNDCARD_H
#include <sys/soundcard.h>
#endif
//#include <sys/ioctl.h>
#include <iostream>

namespace Phonon
{
namespace Fake
{
AudioOutput::AudioOutput(QObject *parent)
    : AbstractAudioOutput(parent)
    , m_device(10000)
    , m_dsp("/dev/dsp")
{
}

AudioOutput::~AudioOutput()
{
}

qreal AudioOutput::volume() const
{
    return m_volume;
}

int AudioOutput::outputDevice() const
{
    return m_device;
}

void AudioOutput::setVolume(qreal newVolume)
{
    m_volume = newVolume;
    emit volumeChanged(m_volume);
}

bool AudioOutput::setOutputDevice(int newDevice)
{
    Q_ASSERT(newDevice >= 10000);
    Q_ASSERT(newDevice <= 10009);
    m_device = newDevice;
    return true;
}

bool AudioOutput::setOutputDevice(const Phonon::AudioOutputDevice &newDevice)
{
    Q_ASSERT(newDevice.index() >= 10000);
    Q_ASSERT(newDevice.index() <= 10009);
    m_device = newDevice.index();
    return true;
}

void AudioOutput::processBuffer(QVector<float> &_buffer)
{
    const QVector<float> &buffer(_buffer);
    // be nice to everybody using KDE with the fake backend and don't play this awful noise :)
    return;

    //static QFile indump("indump");
    //if (!indump.isOpen())
        //indump.open(QIODevice::WriteOnly);
    //static QFile outdump("outdump");
    //if (!outdump.isOpen())
        //outdump.open(QIODevice::WriteOnly);
    openDevice();
    if (!m_dsp.isOpen())
        return;

    // we dump the data in /dev/dsp
    qint16 *pcm = new qint16[2 *buffer.size()]; // 2 *for stereo
    char *towrite = reinterpret_cast<char *>(pcm);
    int converted;
    for (int i = 0; i < buffer.size(); ++i)
    {
        //indump.write(QByteArray::number(buffer[i]) + "\n");
        converted = static_cast<qint16>(m_volume * buffer[i] * static_cast<float>(0x7FFF));
        //outdump.write(QByteArray::number(converted) + "\n");
         *pcm++ = converted;
         *pcm++ = converted;
    }
    int size = sizeof(qint16) * 2 * buffer.size();
    int written;
    while (size > 0)
    {
        written = m_dsp.write(towrite, size);
        // QFSFileEngine loops until errno != EINTR
        if (written < 0)
            break;
        size = size - written;
        if (size > 0)
        {
            towrite += written;
            //kWarning() << "only " << written << " bytes written to /dev/dsp";
        }
    }

    pcm -= 2 *buffer.size();
    delete[] pcm;
}

void AudioOutput::openDevice()
{
    if (m_dsp.isOpen())
        return;

#ifdef HAVE_SYS_SOUNDCARD_H
    if (m_dsp.open(QIODevice::WriteOnly))
    {
        int fd = m_dsp.handle();
        int format = AFMT_S16_LE;
        int stereo = 1;
        int samplingRate = 44100;
        ioctl(fd, SNDCTL_DSP_SETFMT, &format);
        ioctl(fd, SNDCTL_DSP_STEREO, &stereo);
        ioctl(fd, SNDCTL_DSP_SPEED, &samplingRate);
    }
#endif
}

void AudioOutput::closeDevice()
{
    m_dsp.close();
}

}} //namespace Phonon::Fake

#include "moc_audiooutput.cpp"
// vim: sw=4 ts=4
<commit_msg>negative indexes come from the platform plugin and are nothing to abort on<commit_after>/*  This file is part of the KDE project
    Copyright (C) 2006-2007 Matthias Kretz <kretz@kde.org>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License version 2 as published by the Free Software Foundation.

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

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

*/

#include "audiooutput.h"
#include <QtCore/QVector>

//#include <phonon/config-alsa.h>

#ifdef HAVE_SYS_SOUNDCARD_H
#include <sys/soundcard.h>
#endif
//#include <sys/ioctl.h>
#include <iostream>

namespace Phonon
{
namespace Fake
{
AudioOutput::AudioOutput(QObject *parent)
    : AbstractAudioOutput(parent)
    , m_device(10000)
    , m_dsp("/dev/dsp")
{
}

AudioOutput::~AudioOutput()
{
}

qreal AudioOutput::volume() const
{
    return m_volume;
}

int AudioOutput::outputDevice() const
{
    return m_device;
}

void AudioOutput::setVolume(qreal newVolume)
{
    m_volume = newVolume;
    emit volumeChanged(m_volume);
}

bool AudioOutput::setOutputDevice(int newDevice)
{
    Q_ASSERT(newDevice >= 10000);
    Q_ASSERT(newDevice <= 10009);
    m_device = newDevice;
    return true;
}

bool AudioOutput::setOutputDevice(const Phonon::AudioOutputDevice &newDevice)
{
    if (newDevice.index() >= 0) {
        Q_ASSERT(newDevice.index() >= 10000);
        Q_ASSERT(newDevice.index() <= 10009);
    }
    m_device = newDevice.index();
    return true;
}

void AudioOutput::processBuffer(QVector<float> &_buffer)
{
    const QVector<float> &buffer(_buffer);
    // be nice to everybody using KDE with the fake backend and don't play this awful noise :)
    return;

    //static QFile indump("indump");
    //if (!indump.isOpen())
        //indump.open(QIODevice::WriteOnly);
    //static QFile outdump("outdump");
    //if (!outdump.isOpen())
        //outdump.open(QIODevice::WriteOnly);
    openDevice();
    if (!m_dsp.isOpen())
        return;

    // we dump the data in /dev/dsp
    qint16 *pcm = new qint16[2 *buffer.size()]; // 2 *for stereo
    char *towrite = reinterpret_cast<char *>(pcm);
    int converted;
    for (int i = 0; i < buffer.size(); ++i)
    {
        //indump.write(QByteArray::number(buffer[i]) + "\n");
        converted = static_cast<qint16>(m_volume * buffer[i] * static_cast<float>(0x7FFF));
        //outdump.write(QByteArray::number(converted) + "\n");
         *pcm++ = converted;
         *pcm++ = converted;
    }
    int size = sizeof(qint16) * 2 * buffer.size();
    int written;
    while (size > 0)
    {
        written = m_dsp.write(towrite, size);
        // QFSFileEngine loops until errno != EINTR
        if (written < 0)
            break;
        size = size - written;
        if (size > 0)
        {
            towrite += written;
            //kWarning() << "only " << written << " bytes written to /dev/dsp";
        }
    }

    pcm -= 2 *buffer.size();
    delete[] pcm;
}

void AudioOutput::openDevice()
{
    if (m_dsp.isOpen())
        return;

#ifdef HAVE_SYS_SOUNDCARD_H
    if (m_dsp.open(QIODevice::WriteOnly))
    {
        int fd = m_dsp.handle();
        int format = AFMT_S16_LE;
        int stereo = 1;
        int samplingRate = 44100;
        ioctl(fd, SNDCTL_DSP_SETFMT, &format);
        ioctl(fd, SNDCTL_DSP_STEREO, &stereo);
        ioctl(fd, SNDCTL_DSP_SPEED, &samplingRate);
    }
#endif
}

void AudioOutput::closeDevice()
{
    m_dsp.close();
}

}} //namespace Phonon::Fake

#include "moc_audiooutput.cpp"
// vim: sw=4 ts=4
<|endoftext|>


<commit_before>//===- FastISelEmitter.cpp - Generate an instruction selector -------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This tablegen backend emits a "fast" instruction selector.
//
// This instruction selection method is designed to emit very poor code
// quickly. Also, it is not designed to do much lowering, so most illegal
// types (e.g. i64 on 32-bit targets) and operations (e.g. calls) are not
// supported and cannot easily be added. Blocks containing operations
// that are not supported need to be handled by a more capable selector,
// such as the SelectionDAG selector.
//
// The intended use for "fast" instruction selection is "-O0" mode
// compilation, where the quality of the generated code is irrelevant when
// weighed against the speed at which the code can be generated.
//
// If compile time is so important, you might wonder why we don't just
// skip codegen all-together, emit LLVM bytecode files, and execute them
// with an interpreter. The answer is that it would complicate linking and
// debugging, and also because that isn't how a compiler is expected to
// work in some circles.
//
// If you need better generated code or more lowering than what this
// instruction selector provides, use the SelectionDAG (DAGISel) instruction
// selector instead. If you're looking here because SelectionDAG isn't fast
// enough, consider looking into improving the SelectionDAG infastructure
// instead. At the time of this writing there remain several major
// opportunities for improvement.
//
//===----------------------------------------------------------------------===//

#include "FastISelEmitter.h"
#include "Record.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Streams.h"
#include "llvm/ADT/VectorExtras.h"
using namespace llvm;

namespace {

/// OperandsSignature - This class holds a description of a list of operand
/// types. It has utility methods for emitting text based on the operands.
///
struct OperandsSignature {
  std::vector<std::string> Operands;

  bool operator<(const OperandsSignature &O) const {
    return Operands < O.Operands;
  }

  bool empty() const { return Operands.empty(); }

  void PrintParameters(std::ostream &OS) const {
    for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
      if (Operands[i] == "r") {
        OS << "unsigned Op" << i;
      } else {
        assert("Unknown operand kind!");
        abort();
      }
      if (i + 1 != e)
        OS << ", ";
    }
  }

  void PrintArguments(std::ostream &OS) const {
    for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
      if (Operands[i] == "r") {
        OS << "Op" << i;
      } else {
        assert("Unknown operand kind!");
        abort();
      }
      if (i + 1 != e)
        OS << ", ";
    }
  }

  void PrintManglingSuffix(std::ostream &OS) const {
    for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
      OS << Operands[i];
    }
  }
};

/// InstructionMemo - This class holds additional information about an
/// instruction needed to emit code for it.
///
struct InstructionMemo {
  std::string Name;
  const CodeGenRegisterClass *RC;
};

}

static std::string getOpcodeName(Record *Op, CodeGenDAGPatterns &CGP) {
  return CGP.getSDNodeInfo(Op).getEnumName();
}

static std::string getLegalCName(std::string OpName) {
  std::string::size_type pos = OpName.find("::");
  if (pos != std::string::npos)
    OpName.replace(pos, 2, "_");
  return OpName;
}

void FastISelEmitter::run(std::ostream &OS) {
  EmitSourceFileHeader("\"Fast\" Instruction Selector for the " +
                       CGP.getTargetInfo().getName() + " target", OS);

  const CodeGenTarget &Target = CGP.getTargetInfo();

  // Get the namespace to insert instructions into.  Make sure not to pick up
  // "TargetInstrInfo" by accidentally getting the namespace off the PHI
  // instruction or something.
  std::string InstNS;
  for (CodeGenTarget::inst_iterator i = Target.inst_begin(),
       e = Target.inst_end(); i != e; ++i) {
    InstNS = i->second.Namespace;
    if (InstNS != "TargetInstrInfo")
      break;
  }

  OS << "namespace llvm {\n";
  OS << "namespace " << InstNS << " {\n";
  OS << "class FastISel;\n";
  OS << "}\n";
  OS << "}\n";
  OS << "\n";

  if (!InstNS.empty()) InstNS += "::";

  typedef std::map<MVT::SimpleValueType, InstructionMemo> TypeMap;
  typedef std::map<std::string, TypeMap> OpcodeTypeMap;
  typedef std::map<OperandsSignature, OpcodeTypeMap> OperandsOpcodeTypeMap;
  OperandsOpcodeTypeMap SimplePatterns;

  // Create the supported type signatures.
  OperandsSignature KnownOperands;
  SimplePatterns[KnownOperands] = OpcodeTypeMap();
  KnownOperands.Operands.push_back("r");
  SimplePatterns[KnownOperands] = OpcodeTypeMap();
  KnownOperands.Operands.push_back("r");
  SimplePatterns[KnownOperands] = OpcodeTypeMap();

  for (CodeGenDAGPatterns::ptm_iterator I = CGP.ptm_begin(),
       E = CGP.ptm_end(); I != E; ++I) {
    const PatternToMatch &Pattern = *I;

    // For now, just look at Instructions, so that we don't have to worry
    // about emitting multiple instructions for a pattern.
    TreePatternNode *Dst = Pattern.getDstPattern();
    if (Dst->isLeaf()) continue;
    Record *Op = Dst->getOperator();
    if (!Op->isSubClassOf("Instruction"))
      continue;
    CodeGenInstruction &II = CGP.getTargetInfo().getInstruction(Op->getName());
    if (II.OperandList.empty())
      continue;
    Record *Op0Rec = II.OperandList[0].Rec;
    if (!Op0Rec->isSubClassOf("RegisterClass"))
      continue;
    const CodeGenRegisterClass *DstRC = &Target.getRegisterClass(Op0Rec);
    if (!DstRC)
      continue;

    // Inspect the pattern.
    TreePatternNode *InstPatNode = Pattern.getSrcPattern();
    if (!InstPatNode) continue;
    if (InstPatNode->isLeaf()) continue;

    Record *InstPatOp = InstPatNode->getOperator();
    std::string OpcodeName = getOpcodeName(InstPatOp, CGP);
    MVT::SimpleValueType VT = InstPatNode->getTypeNum(0);

    // For now, filter out instructions which just set a register to
    // an Operand, like MOV32ri.
    if (InstPatOp->isSubClassOf("Operand"))
      continue;

    // Check all the operands. For now only accept register operands.
    OperandsSignature Operands;
    for (unsigned i = 0, e = InstPatNode->getNumChildren(); i != e; ++i) {
      TreePatternNode *Op = InstPatNode->getChild(i);
      if (!Op->isLeaf())
        goto continue_label;
      DefInit *OpDI = dynamic_cast<DefInit*>(Op->getLeafValue());
      if (!OpDI)
        goto continue_label;
      Record *OpLeafRec = OpDI->getDef();
      if (!OpLeafRec->isSubClassOf("RegisterClass"))
        goto continue_label;
      const CodeGenRegisterClass *RC = &Target.getRegisterClass(OpLeafRec);
      if (!RC)
        goto continue_label;
      if (Op->getTypeNum(0) != VT)
        goto continue_label;
      Operands.Operands.push_back("r");
    }

    // If it's not a known signature, ignore it.
    if (!SimplePatterns.count(Operands))
      continue;

    // Ok, we found a pattern that we can handle. Remember it.
    {
      InstructionMemo Memo = { Pattern.getDstPattern()->getOperator()->getName(),
                               DstRC };
      SimplePatterns[Operands][OpcodeName][VT] = Memo;
    }

  continue_label:;
  }

  OS << "#include \"llvm/CodeGen/FastISel.h\"\n";
  OS << "\n";
  OS << "namespace llvm {\n";
  OS << "\n";

  // Declare the target FastISel class.
  OS << "class " << InstNS << "FastISel : public llvm::FastISel {\n";
  for (OperandsOpcodeTypeMap::const_iterator OI = SimplePatterns.begin(),
       OE = SimplePatterns.end(); OI != OE; ++OI) {
    const OperandsSignature &Operands = OI->first;
    const OpcodeTypeMap &OTM = OI->second;

    for (OpcodeTypeMap::const_iterator I = OTM.begin(), E = OTM.end();
         I != E; ++I) {
      const std::string &Opcode = I->first;
      const TypeMap &TM = I->second;

      for (TypeMap::const_iterator TI = TM.begin(), TE = TM.end();
           TI != TE; ++TI) {
        MVT::SimpleValueType VT = TI->first;

        OS << "  unsigned FastEmit_" << getLegalCName(Opcode)
           << "_" << getLegalCName(getName(VT)) << "(";
        Operands.PrintParameters(OS);
        OS << ");\n";
      }

      OS << "  unsigned FastEmit_" << getLegalCName(Opcode)
         << "(MVT::SimpleValueType VT";
      if (!Operands.empty())
        OS << ", ";
      Operands.PrintParameters(OS);
      OS << ");\n";
    }

    OS << "unsigned FastEmit_";
    Operands.PrintManglingSuffix(OS);
    OS << "(MVT::SimpleValueType VT, ISD::NodeType Opcode";
    if (!Operands.empty())
      OS << ", ";
    Operands.PrintParameters(OS);
    OS << ");\n";
  }
  OS << "public:\n";
  OS << "  FastISel(MachineBasicBlock *mbb, MachineFunction *mf, ";
  OS << "const TargetInstrInfo *tii) : llvm::FastISel(mbb, mf, tii) {}\n";
  OS << "};\n";
  OS << "\n";

  // Define the target FastISel creation function.
  OS << "llvm::FastISel *" << InstNS
     << "createFastISel(MachineBasicBlock *mbb, MachineFunction *mf, ";
  OS << "const TargetInstrInfo *tii) {\n";
  OS << "  return new " << InstNS << "FastISel(mbb, mf, tii);\n";
  OS << "}\n";
  OS << "\n";

  // Now emit code for all the patterns that we collected.
  for (OperandsOpcodeTypeMap::const_iterator OI = SimplePatterns.begin(),
       OE = SimplePatterns.end(); OI != OE; ++OI) {
    const OperandsSignature &Operands = OI->first;
    const OpcodeTypeMap &OTM = OI->second;

    for (OpcodeTypeMap::const_iterator I = OTM.begin(), E = OTM.end();
         I != E; ++I) {
      const std::string &Opcode = I->first;
      const TypeMap &TM = I->second;

      OS << "// FastEmit functions for " << Opcode << ".\n";
      OS << "\n";

      // Emit one function for each opcode,type pair.
      for (TypeMap::const_iterator TI = TM.begin(), TE = TM.end();
           TI != TE; ++TI) {
        MVT::SimpleValueType VT = TI->first;
        const InstructionMemo &Memo = TI->second;

        OS << "unsigned " << InstNS << "FastISel::FastEmit_"
           << getLegalCName(Opcode)
           << "_" << getLegalCName(getName(VT)) << "(";
        Operands.PrintParameters(OS);
        OS << ") {\n";
        OS << "  return FastEmitInst_";
        Operands.PrintManglingSuffix(OS);
        OS << "(" << InstNS << Memo.Name << ", ";
        OS << InstNS << Memo.RC->getName() << "RegisterClass";
        if (!Operands.empty())
          OS << ", ";
        Operands.PrintArguments(OS);
        OS << ");\n";
        OS << "}\n";
        OS << "\n";
      }

      // Emit one function for the opcode that demultiplexes based on the type.
      OS << "unsigned " << InstNS << "FastISel::FastEmit_"
         << getLegalCName(Opcode) << "(MVT::SimpleValueType VT";
      if (!Operands.empty())
        OS << ", ";
      Operands.PrintParameters(OS);
      OS << ") {\n";
      OS << "  switch (VT) {\n";
      for (TypeMap::const_iterator TI = TM.begin(), TE = TM.end();
           TI != TE; ++TI) {
        MVT::SimpleValueType VT = TI->first;
        std::string TypeName = getName(VT);
        OS << "  case " << TypeName << ": return FastEmit_"
           << getLegalCName(Opcode) << "_" << getLegalCName(TypeName) << "(";
        Operands.PrintArguments(OS);
        OS << ");\n";
      }
      OS << "  default: return 0;\n";
      OS << "  }\n";
      OS << "}\n";
      OS << "\n";
    }

    // Emit one function for the operand signature that demultiplexes based
    // on opcode and type.
    OS << "unsigned " << InstNS << "FastISel::FastEmit_";
    Operands.PrintManglingSuffix(OS);
    OS << "(MVT::SimpleValueType VT, ISD::NodeType Opcode";
    if (!Operands.empty())
      OS << ", ";
    Operands.PrintParameters(OS);
    OS << ") {\n";
    OS << "  switch (Opcode) {\n";
    for (OpcodeTypeMap::const_iterator I = OTM.begin(), E = OTM.end();
         I != E; ++I) {
      const std::string &Opcode = I->first;

      OS << "  case " << Opcode << ": return FastEmit_"
         << getLegalCName(Opcode) << "(VT";
      if (!Operands.empty())
        OS << ", ";
      Operands.PrintArguments(OS);
      OS << ");\n";
    }
    OS << "  default: return 0;\n";
    OS << "  }\n";
    OS << "}\n";
    OS << "\n";
  }

  OS << "}\n";
}

// todo: really filter out Constants
<commit_msg>80 columns.<commit_after>//===- FastISelEmitter.cpp - Generate an instruction selector -------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This tablegen backend emits a "fast" instruction selector.
//
// This instruction selection method is designed to emit very poor code
// quickly. Also, it is not designed to do much lowering, so most illegal
// types (e.g. i64 on 32-bit targets) and operations (e.g. calls) are not
// supported and cannot easily be added. Blocks containing operations
// that are not supported need to be handled by a more capable selector,
// such as the SelectionDAG selector.
//
// The intended use for "fast" instruction selection is "-O0" mode
// compilation, where the quality of the generated code is irrelevant when
// weighed against the speed at which the code can be generated.
//
// If compile time is so important, you might wonder why we don't just
// skip codegen all-together, emit LLVM bytecode files, and execute them
// with an interpreter. The answer is that it would complicate linking and
// debugging, and also because that isn't how a compiler is expected to
// work in some circles.
//
// If you need better generated code or more lowering than what this
// instruction selector provides, use the SelectionDAG (DAGISel) instruction
// selector instead. If you're looking here because SelectionDAG isn't fast
// enough, consider looking into improving the SelectionDAG infastructure
// instead. At the time of this writing there remain several major
// opportunities for improvement.
//
//===----------------------------------------------------------------------===//

#include "FastISelEmitter.h"
#include "Record.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Streams.h"
#include "llvm/ADT/VectorExtras.h"
using namespace llvm;

namespace {

/// OperandsSignature - This class holds a description of a list of operand
/// types. It has utility methods for emitting text based on the operands.
///
struct OperandsSignature {
  std::vector<std::string> Operands;

  bool operator<(const OperandsSignature &O) const {
    return Operands < O.Operands;
  }

  bool empty() const { return Operands.empty(); }

  void PrintParameters(std::ostream &OS) const {
    for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
      if (Operands[i] == "r") {
        OS << "unsigned Op" << i;
      } else {
        assert("Unknown operand kind!");
        abort();
      }
      if (i + 1 != e)
        OS << ", ";
    }
  }

  void PrintArguments(std::ostream &OS) const {
    for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
      if (Operands[i] == "r") {
        OS << "Op" << i;
      } else {
        assert("Unknown operand kind!");
        abort();
      }
      if (i + 1 != e)
        OS << ", ";
    }
  }

  void PrintManglingSuffix(std::ostream &OS) const {
    for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
      OS << Operands[i];
    }
  }
};

/// InstructionMemo - This class holds additional information about an
/// instruction needed to emit code for it.
///
struct InstructionMemo {
  std::string Name;
  const CodeGenRegisterClass *RC;
};

}

static std::string getOpcodeName(Record *Op, CodeGenDAGPatterns &CGP) {
  return CGP.getSDNodeInfo(Op).getEnumName();
}

static std::string getLegalCName(std::string OpName) {
  std::string::size_type pos = OpName.find("::");
  if (pos != std::string::npos)
    OpName.replace(pos, 2, "_");
  return OpName;
}

void FastISelEmitter::run(std::ostream &OS) {
  EmitSourceFileHeader("\"Fast\" Instruction Selector for the " +
                       CGP.getTargetInfo().getName() + " target", OS);

  const CodeGenTarget &Target = CGP.getTargetInfo();

  // Get the namespace to insert instructions into.  Make sure not to pick up
  // "TargetInstrInfo" by accidentally getting the namespace off the PHI
  // instruction or something.
  std::string InstNS;
  for (CodeGenTarget::inst_iterator i = Target.inst_begin(),
       e = Target.inst_end(); i != e; ++i) {
    InstNS = i->second.Namespace;
    if (InstNS != "TargetInstrInfo")
      break;
  }

  OS << "namespace llvm {\n";
  OS << "namespace " << InstNS << " {\n";
  OS << "class FastISel;\n";
  OS << "}\n";
  OS << "}\n";
  OS << "\n";

  if (!InstNS.empty()) InstNS += "::";

  typedef std::map<MVT::SimpleValueType, InstructionMemo> TypeMap;
  typedef std::map<std::string, TypeMap> OpcodeTypeMap;
  typedef std::map<OperandsSignature, OpcodeTypeMap> OperandsOpcodeTypeMap;
  OperandsOpcodeTypeMap SimplePatterns;

  // Create the supported type signatures.
  OperandsSignature KnownOperands;
  SimplePatterns[KnownOperands] = OpcodeTypeMap();
  KnownOperands.Operands.push_back("r");
  SimplePatterns[KnownOperands] = OpcodeTypeMap();
  KnownOperands.Operands.push_back("r");
  SimplePatterns[KnownOperands] = OpcodeTypeMap();

  for (CodeGenDAGPatterns::ptm_iterator I = CGP.ptm_begin(),
       E = CGP.ptm_end(); I != E; ++I) {
    const PatternToMatch &Pattern = *I;

    // For now, just look at Instructions, so that we don't have to worry
    // about emitting multiple instructions for a pattern.
    TreePatternNode *Dst = Pattern.getDstPattern();
    if (Dst->isLeaf()) continue;
    Record *Op = Dst->getOperator();
    if (!Op->isSubClassOf("Instruction"))
      continue;
    CodeGenInstruction &II = CGP.getTargetInfo().getInstruction(Op->getName());
    if (II.OperandList.empty())
      continue;
    Record *Op0Rec = II.OperandList[0].Rec;
    if (!Op0Rec->isSubClassOf("RegisterClass"))
      continue;
    const CodeGenRegisterClass *DstRC = &Target.getRegisterClass(Op0Rec);
    if (!DstRC)
      continue;

    // Inspect the pattern.
    TreePatternNode *InstPatNode = Pattern.getSrcPattern();
    if (!InstPatNode) continue;
    if (InstPatNode->isLeaf()) continue;

    Record *InstPatOp = InstPatNode->getOperator();
    std::string OpcodeName = getOpcodeName(InstPatOp, CGP);
    MVT::SimpleValueType VT = InstPatNode->getTypeNum(0);

    // For now, filter out instructions which just set a register to
    // an Operand, like MOV32ri.
    if (InstPatOp->isSubClassOf("Operand"))
      continue;

    // Check all the operands. For now only accept register operands.
    OperandsSignature Operands;
    for (unsigned i = 0, e = InstPatNode->getNumChildren(); i != e; ++i) {
      TreePatternNode *Op = InstPatNode->getChild(i);
      if (!Op->isLeaf())
        goto continue_label;
      DefInit *OpDI = dynamic_cast<DefInit*>(Op->getLeafValue());
      if (!OpDI)
        goto continue_label;
      Record *OpLeafRec = OpDI->getDef();
      if (!OpLeafRec->isSubClassOf("RegisterClass"))
        goto continue_label;
      const CodeGenRegisterClass *RC = &Target.getRegisterClass(OpLeafRec);
      if (!RC)
        goto continue_label;
      if (Op->getTypeNum(0) != VT)
        goto continue_label;
      Operands.Operands.push_back("r");
    }

    // If it's not a known signature, ignore it.
    if (!SimplePatterns.count(Operands))
      continue;

    // Ok, we found a pattern that we can handle. Remember it.
    {
      InstructionMemo Memo = {
        Pattern.getDstPattern()->getOperator()->getName(),
        DstRC
      };
      SimplePatterns[Operands][OpcodeName][VT] = Memo;
    }

  continue_label:;
  }

  OS << "#include \"llvm/CodeGen/FastISel.h\"\n";
  OS << "\n";
  OS << "namespace llvm {\n";
  OS << "\n";

  // Declare the target FastISel class.
  OS << "class " << InstNS << "FastISel : public llvm::FastISel {\n";
  for (OperandsOpcodeTypeMap::const_iterator OI = SimplePatterns.begin(),
       OE = SimplePatterns.end(); OI != OE; ++OI) {
    const OperandsSignature &Operands = OI->first;
    const OpcodeTypeMap &OTM = OI->second;

    for (OpcodeTypeMap::const_iterator I = OTM.begin(), E = OTM.end();
         I != E; ++I) {
      const std::string &Opcode = I->first;
      const TypeMap &TM = I->second;

      for (TypeMap::const_iterator TI = TM.begin(), TE = TM.end();
           TI != TE; ++TI) {
        MVT::SimpleValueType VT = TI->first;

        OS << "  unsigned FastEmit_" << getLegalCName(Opcode)
           << "_" << getLegalCName(getName(VT)) << "(";
        Operands.PrintParameters(OS);
        OS << ");\n";
      }

      OS << "  unsigned FastEmit_" << getLegalCName(Opcode)
         << "(MVT::SimpleValueType VT";
      if (!Operands.empty())
        OS << ", ";
      Operands.PrintParameters(OS);
      OS << ");\n";
    }

    OS << "unsigned FastEmit_";
    Operands.PrintManglingSuffix(OS);
    OS << "(MVT::SimpleValueType VT, ISD::NodeType Opcode";
    if (!Operands.empty())
      OS << ", ";
    Operands.PrintParameters(OS);
    OS << ");\n";
  }
  OS << "public:\n";
  OS << "  FastISel(MachineBasicBlock *mbb, MachineFunction *mf, ";
  OS << "const TargetInstrInfo *tii) : llvm::FastISel(mbb, mf, tii) {}\n";
  OS << "};\n";
  OS << "\n";

  // Define the target FastISel creation function.
  OS << "llvm::FastISel *" << InstNS
     << "createFastISel(MachineBasicBlock *mbb, MachineFunction *mf, ";
  OS << "const TargetInstrInfo *tii) {\n";
  OS << "  return new " << InstNS << "FastISel(mbb, mf, tii);\n";
  OS << "}\n";
  OS << "\n";

  // Now emit code for all the patterns that we collected.
  for (OperandsOpcodeTypeMap::const_iterator OI = SimplePatterns.begin(),
       OE = SimplePatterns.end(); OI != OE; ++OI) {
    const OperandsSignature &Operands = OI->first;
    const OpcodeTypeMap &OTM = OI->second;

    for (OpcodeTypeMap::const_iterator I = OTM.begin(), E = OTM.end();
         I != E; ++I) {
      const std::string &Opcode = I->first;
      const TypeMap &TM = I->second;

      OS << "// FastEmit functions for " << Opcode << ".\n";
      OS << "\n";

      // Emit one function for each opcode,type pair.
      for (TypeMap::const_iterator TI = TM.begin(), TE = TM.end();
           TI != TE; ++TI) {
        MVT::SimpleValueType VT = TI->first;
        const InstructionMemo &Memo = TI->second;

        OS << "unsigned " << InstNS << "FastISel::FastEmit_"
           << getLegalCName(Opcode)
           << "_" << getLegalCName(getName(VT)) << "(";
        Operands.PrintParameters(OS);
        OS << ") {\n";
        OS << "  return FastEmitInst_";
        Operands.PrintManglingSuffix(OS);
        OS << "(" << InstNS << Memo.Name << ", ";
        OS << InstNS << Memo.RC->getName() << "RegisterClass";
        if (!Operands.empty())
          OS << ", ";
        Operands.PrintArguments(OS);
        OS << ");\n";
        OS << "}\n";
        OS << "\n";
      }

      // Emit one function for the opcode that demultiplexes based on the type.
      OS << "unsigned " << InstNS << "FastISel::FastEmit_"
         << getLegalCName(Opcode) << "(MVT::SimpleValueType VT";
      if (!Operands.empty())
        OS << ", ";
      Operands.PrintParameters(OS);
      OS << ") {\n";
      OS << "  switch (VT) {\n";
      for (TypeMap::const_iterator TI = TM.begin(), TE = TM.end();
           TI != TE; ++TI) {
        MVT::SimpleValueType VT = TI->first;
        std::string TypeName = getName(VT);
        OS << "  case " << TypeName << ": return FastEmit_"
           << getLegalCName(Opcode) << "_" << getLegalCName(TypeName) << "(";
        Operands.PrintArguments(OS);
        OS << ");\n";
      }
      OS << "  default: return 0;\n";
      OS << "  }\n";
      OS << "}\n";
      OS << "\n";
    }

    // Emit one function for the operand signature that demultiplexes based
    // on opcode and type.
    OS << "unsigned " << InstNS << "FastISel::FastEmit_";
    Operands.PrintManglingSuffix(OS);
    OS << "(MVT::SimpleValueType VT, ISD::NodeType Opcode";
    if (!Operands.empty())
      OS << ", ";
    Operands.PrintParameters(OS);
    OS << ") {\n";
    OS << "  switch (Opcode) {\n";
    for (OpcodeTypeMap::const_iterator I = OTM.begin(), E = OTM.end();
         I != E; ++I) {
      const std::string &Opcode = I->first;

      OS << "  case " << Opcode << ": return FastEmit_"
         << getLegalCName(Opcode) << "(VT";
      if (!Operands.empty())
        OS << ", ";
      Operands.PrintArguments(OS);
      OS << ");\n";
    }
    OS << "  default: return 0;\n";
    OS << "  }\n";
    OS << "}\n";
    OS << "\n";
  }

  OS << "}\n";
}

// todo: really filter out Constants
<|endoftext|>


<commit_before>/* UVa problem: rubik's cycle
 *
 * Topic: combinatorics
 *
 * Level: trivial
 *
 * Brief problem description:
 *
 *   Given a rubiks cube, capital letter 90 deg cw rotate,
 *   lowercase 90 deg ccw rotate, a sequence of movements,
 *   solve the cube
 *
 * Solution Summary:
 *
 *
 *
 * Used Resources:
 *
 *  cp3
 *
 * I hereby certify that I have produced the following solution myself
 * using the resources listed above in accordance with the CMPUT 403
 * collaboration policy.
 *
 * --- Dennis Truong
 */
#include <iostream>
using namespace std;

int solve(){

    return 0;
}

int main() {
    string in;
    while (cin >> in) {
        for (int i = 0; i < in.length(); i++){
            string r = in[i];
        }
    }
    return 0;
}<commit_msg>rubiks cycle brute force<commit_after>/* UVa problem: rubik's cycle
 *
 * Topic: combinatorics
 *
 * Level: trivial
 *
 * Brief problem description:
 *
 *   Given a rubiks cube, capital letter 90 deg cw rotate,
 *   lowercase 90 deg ccw rotate, a sequence of movements,
 *   solve the cube
 *
 * Solution Summary:
 *
 *   todo: find lcm of the cube permutations or extended gcd
 *   actual : brute force the cube
 *
 * Used Resources:
 *
 *  cp3, code archive
 *
 * I hereby certify that I have produced the following solution myself
 * using the resources listed above in accordance with the CMPUT 403
 * collaboration policy.
 *
 * --- Dennis Truong
 */
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <map>
using namespace std;

int idx, i, j, d, N, cnt;
map<char,int> r;
string in;
typedef struct
{
    char g[9][12];
} Cube;

int cx[6] = {4, 4, 4, 4, 1, 7};
int cy[6] = {1, 4, 7, 10, 4, 4};

int rx[6][4][3] = {{{0, 1, 2}, {5, 4, 3}, {6, 7, 8}, {3, 4, 5}},
                   {{2, 2, 2}, {5, 4, 3}, {6, 6, 6}, {3, 4, 5}},
                   {{2, 1, 0}, {5, 4, 3}, {8, 7, 6}, {3, 4, 5}},
                   {{5, 4, 3}, {8, 8, 8}, {3, 4, 5}, {0, 0, 0}},
                   {{3, 3, 3}, {3, 3, 3}, {3, 3, 3}, {3, 3, 3}},
                   {{5, 5, 5}, {5, 5, 5}, {5, 5, 5}, {5, 5, 5}}};

int ry[6][4][3] = {{{3, 3, 3}, {11, 11, 11}, {3, 3, 3}, {3, 3, 3}},
                   {{3, 4, 5}, {2, 2, 2}, {5, 4, 3}, {6, 6, 6}},
                   {{5, 5, 5}, {5, 5, 5}, {5, 5, 5}, {9, 9, 9}},
                   {{8, 8, 8}, {3, 4, 5}, {0, 0, 0}, {5, 4, 3}},
                   {{0, 1, 2}, {3, 4, 5}, {6, 7, 8}, {9, 10, 11}},
                   {{11, 10, 9}, {8, 7, 6}, {5, 4, 3}, {2, 1, 0}}};

int isSolved(Cube c)
{
    int i, x, y;

    for (i = 0; i < 6; i++)
        for (x = cx[i] - 1; x <= cx[i] + 1; x++)
            for (y = cy[i] - 1; y <= cy[i] + 1; y++)
                if (c.g[x][y] != c.g[cx[i]][cy[i]])
                    return 0;
    return 1;
}

Cube Rotate(Cube c, int f)
{
    char t[3][3];
    int i, j, x = cx[f], y = cy[f];

    for (i = 0; i < 3; i++)
        for (j = 0; j < 3; j++)
            t[i][j] = c.g[x + i - 1][y + j - 1];

    for (i = 0; i < 3; i++)
        for (j = 0; j < 3; j++)
            c.g[x + i - 1][y + j - 1] = t[2 - j][i];

    for (i = 0; i < 3; i++)
        t[0][i] = c.g[rx[f][0][i]][ry[f][0][i]];

    for (j = 0; j < 3; j++)
        for (i = 0; i < 3; i++)
            c.g[rx[f][j][i]][ry[f][j][i]] =
                c.g[rx[f][j + 1][i]][ry[f][j + 1][i]];

    for (i = 0; i < 3; i++)
        c.g[rx[f][j][i]][ry[f][j][i]] = t[0][i];

    return c;
}

void printCube(Cube c)
{
    int i, j;

    for (i = 0; i < 9; i++)
    {
        for (j = 0; j < 12; j++)
            printf("%c", c.g[i][j] ? c.g[i][j] : ' ');
        printf("\n");
    }
    printf("\n");
}
void rotate(Cube & c) {
    char face = in[idx];
    bool ccw = islower(face);
    d = r[face];
    if (ccw) {
        c = Rotate(c, d);
        c = Rotate(c, d);
        c = Rotate(c, d);
    } else {
        c = Rotate(c, d);
    }
            ++idx;
            if (idx == N) cnt++;
            idx = idx % N;
}
int main()
{
    r['U'] = r['u'] = 4;
    r['D'] = r['d'] = 5;
    r['L'] = r['l'] = 0;
    r['R'] = r['r'] = 2;
    r['F'] = r['f'] = 1;
    r['B'] = r['b'] = 3;

    Cube c;
    while (cin >> in)
    {
        N = in.length();
        memset(c.g, 0, sizeof(c.g));
        for (i = 0; i < 3; i++)
        {
            for (j = 3; j < 6; j++)
            {
                c.g[i][j] = '4';
            }
        }
        for (i = 3; i < 6; i++)
        {
            for (j = 0; j < 3; j++) c.g[i][j] = '0';
            for (j = 3; j < 6; j++) c.g[i][j] = '1';
            for (j = 6; j < 9; j++) c.g[i][j] = '2';
            for (j = 9; j < 12; j++) c.g[i][j] = '3';
        }
        for (i = 6; i < 9; i++)
        {
            for (j = 3; j < 6; j++)
            {
                c.g[i][j] = '5';
            }
        }
        cnt = 0; idx = 0;
        while(true) {
            for (int j = 0; j < N; j++) rotate(c);
            if (isSolved(c)) break;
        }
        cout << cnt << endl;
    }

    return 0;
}
<|endoftext|>


<commit_before>// Copyright (c) 2011 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 "ui/gfx/compositor/compositor_cc.h"

#include "base/command_line.h"
#include "third_party/skia/include/images/SkImageEncoder.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebCompositor.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebFloatPoint.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebRect.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebSize.h"
#include "ui/gfx/compositor/compositor_switches.h"
#include "ui/gfx/compositor/test_web_graphics_context_3d.h"
#include "ui/gfx/compositor/layer.h"
#include "ui/gfx/gl/gl_context.h"
#include "ui/gfx/gl/gl_surface.h"
#include "ui/gfx/gl/gl_implementation.h"
#include "ui/gfx/gl/scoped_make_current.h"
#include "webkit/glue/webthread_impl.h"
#include "webkit/gpu/webgraphicscontext3d_in_process_impl.h"

namespace {
webkit_glue::WebThreadImpl* g_compositor_thread = NULL;
}  // anonymous namespace

namespace ui {

SharedResourcesCC::SharedResourcesCC() : initialized_(false) {
}

SharedResourcesCC::~SharedResourcesCC() {
}

// static
SharedResourcesCC* SharedResourcesCC::GetInstance() {
  // We use LeakySingletonTraits so that we don't race with
  // the tear down of the gl_bindings.
  SharedResourcesCC* instance = Singleton<SharedResourcesCC,
      LeakySingletonTraits<SharedResourcesCC> >::get();
  if (instance->Initialize()) {
    return instance;
  } else {
    instance->Destroy();
    return NULL;
  }
}

bool SharedResourcesCC::Initialize() {
  if (initialized_)
    return true;

  {
    // The following line of code exists soley to disable IO restrictions
    // on this thread long enough to perform the GL bindings.
    // TODO(wjmaclean) Remove this when GL initialisation cleaned up.
    base::ThreadRestrictions::ScopedAllowIO allow_io;
    if (!gfx::GLSurface::InitializeOneOff() ||
        gfx::GetGLImplementation() == gfx::kGLImplementationNone) {
      LOG(ERROR) << "Could not load the GL bindings";
      return false;
    }
  }

  surface_ = gfx::GLSurface::CreateOffscreenGLSurface(false, gfx::Size(1, 1));
  if (!surface_.get()) {
    LOG(ERROR) << "Unable to create offscreen GL surface.";
    return false;
  }

  context_ = gfx::GLContext::CreateGLContext(
      NULL, surface_.get(), gfx::PreferIntegratedGpu);
  if (!context_.get()) {
    LOG(ERROR) << "Unable to create GL context.";
    return false;
  }

  initialized_ = true;
  return true;
}

void SharedResourcesCC::Destroy() {
  context_ = NULL;
  surface_ = NULL;

  initialized_ = false;
}

gfx::ScopedMakeCurrent* SharedResourcesCC::GetScopedMakeCurrent() {
  DCHECK(initialized_);
  if (initialized_)
    return new gfx::ScopedMakeCurrent(context_.get(), surface_.get());
  else
    return NULL;
}

void* SharedResourcesCC::GetDisplay() {
  return surface_->GetDisplay();
}

gfx::GLShareGroup* SharedResourcesCC::GetShareGroup() {
  DCHECK(initialized_);
  return context_->share_group();
}

TextureCC::TextureCC()
    : texture_id_(0),
      flipped_(false) {
}

void TextureCC::SetCanvas(const SkCanvas& canvas,
                          const gfx::Point& origin,
                          const gfx::Size& overall_size) {
  NOTREACHED();
}

void TextureCC::Draw(const ui::TextureDrawParams& params,
                     const gfx::Rect& clip_bounds_in_texture) {
  NOTREACHED();
}

// static
bool CompositorCC::test_context_enabled_ = false;

CompositorCC::CompositorCC(CompositorDelegate* delegate,
                           gfx::AcceleratedWidget widget,
                           const gfx::Size& size)
    : Compositor(delegate, size),
      widget_(widget),
      root_web_layer_(WebKit::WebLayer::create(this)) {
  WebKit::WebLayerTreeView::Settings settings;
  CommandLine* command_line = CommandLine::ForCurrentProcess();
  settings.showFPSCounter =
     command_line->HasSwitch(switches::kUIShowFPSCounter);
  settings.showPlatformLayerTree =
      command_line->HasSwitch(switches::kUIShowLayerTree);
#ifndef WEBCOMPOSITOR_HAS_INITIALIZE
  settings.enableCompositorThread = !!g_compositor_thread;
#endif
  host_ = WebKit::WebLayerTreeView::create(this, root_web_layer_, settings);
  root_web_layer_.setAnchorPoint(WebKit::WebFloatPoint(0.f, 0.f));
  OnWidgetSizeChanged();
}

CompositorCC::~CompositorCC() {
}

void CompositorCC::Initialize(bool use_thread) {
  if (use_thread)
    g_compositor_thread = new webkit_glue::WebThreadImpl("Browser Compositor");
#ifdef WEBCOMPOSITOR_HAS_INITIALIZE
  WebKit::WebCompositor::initialize(g_compositor_thread);
#else
  if (use_thread)
    WebKit::WebCompositor::setThread(g_compositor_thread);
#endif
}

void CompositorCC::Terminate() {
#ifdef WEBCOMPOSITOR_HAS_INITIALIZE
  WebKit::WebCompositor::shutdown();
#endif
  DCHECK(g_compositor_thread);
  delete g_compositor_thread;
  g_compositor_thread = NULL;
}

// static
void CompositorCC::EnableTestContextIfNecessary() {
  // TODO: only do this if command line param not set.
  test_context_enabled_ = true;
}

Texture* CompositorCC::CreateTexture() {
  NOTREACHED();
  return NULL;
}

void CompositorCC::Blur(const gfx::Rect& bounds) {
  NOTIMPLEMENTED();
}

void CompositorCC::ScheduleDraw() {
  if (g_compositor_thread)
    host_.composite();
  else
    Compositor::ScheduleDraw();
}

void CompositorCC::OnNotifyStart(bool clear) {
}

void CompositorCC::OnNotifyEnd() {
}

void CompositorCC::OnWidgetSizeChanged() {
  host_.setViewportSize(size());
  root_web_layer_.setBounds(size());
}

void CompositorCC::OnRootLayerChanged() {
  root_web_layer_.removeAllChildren();
  if (root_layer())
    root_web_layer_.addChild(root_layer()->web_layer());
}

void CompositorCC::DrawTree() {
  host_.composite();
}

bool CompositorCC::ReadPixels(SkBitmap* bitmap, const gfx::Rect& bounds) {
  if (bounds.right() > size().width() || bounds.bottom() > size().height())
    return false;
  // Convert to OpenGL coordinates.
  gfx::Point new_origin(bounds.x(),
                        size().height() - bounds.height() - bounds.y());

  bitmap->setConfig(SkBitmap::kARGB_8888_Config,
                    bounds.width(), bounds.height());
  bitmap->allocPixels();
  SkAutoLockPixels lock_image(*bitmap);
  unsigned char* pixels = static_cast<unsigned char*>(bitmap->getPixels());
  if (host_.compositeAndReadback(pixels,
                                 gfx::Rect(new_origin, bounds.size()))) {
    SwizzleRGBAToBGRAAndFlip(pixels, bounds.size());
    return true;
  }
  return false;
}

void CompositorCC::animateAndLayout(double frameBeginTime) {
}

void CompositorCC::applyScrollAndScale(const WebKit::WebSize& scrollDelta,
                                       float scaleFactor) {
}

void CompositorCC::applyScrollDelta(const WebKit::WebSize&) {
}

WebKit::WebGraphicsContext3D* CompositorCC::createContext3D() {
  WebKit::WebGraphicsContext3D* context;
  if (test_context_enabled_) {
    context = new TestWebGraphicsContext3D();
  } else {
    gfx::GLShareGroup* share_group =
        SharedResourcesCC::GetInstance()->GetShareGroup();
    context = new webkit::gpu::WebGraphicsContext3DInProcessImpl(
        widget_, share_group);
  }
  WebKit::WebGraphicsContext3D::Attributes attrs;
  context->initialize(attrs, 0, true);

  CommandLine* command_line = CommandLine::ForCurrentProcess();
  if (!command_line->HasSwitch(switches::kDisableUIVsync)) {
    context->makeContextCurrent();
    gfx::GLContext* gl_context = gfx::GLContext::GetCurrent();
    gl_context->SetSwapInterval(1);
    gl_context->ReleaseCurrent(NULL);
  }

  return context;
}

void CompositorCC::didRebindGraphicsContext(bool success) {
}

void CompositorCC::scheduleComposite() {
  ScheduleDraw();
}

void CompositorCC::notifyNeedsComposite() {
  ScheduleDraw();
}

Compositor* Compositor::Create(CompositorDelegate* owner,
                               gfx::AcceleratedWidget widget,
                               const gfx::Size& size) {
  return new CompositorCC(owner, widget, size);
}

}  // namespace ui
<commit_msg>Fixes leak/crash in CompositorCC.<commit_after>// Copyright (c) 2011 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 "ui/gfx/compositor/compositor_cc.h"

#include "base/command_line.h"
#include "third_party/skia/include/images/SkImageEncoder.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebCompositor.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebFloatPoint.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebRect.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebSize.h"
#include "ui/gfx/compositor/compositor_switches.h"
#include "ui/gfx/compositor/test_web_graphics_context_3d.h"
#include "ui/gfx/compositor/layer.h"
#include "ui/gfx/gl/gl_context.h"
#include "ui/gfx/gl/gl_surface.h"
#include "ui/gfx/gl/gl_implementation.h"
#include "ui/gfx/gl/scoped_make_current.h"
#include "webkit/glue/webthread_impl.h"
#include "webkit/gpu/webgraphicscontext3d_in_process_impl.h"

namespace {
webkit_glue::WebThreadImpl* g_compositor_thread = NULL;
}  // anonymous namespace

namespace ui {

SharedResourcesCC::SharedResourcesCC() : initialized_(false) {
}

SharedResourcesCC::~SharedResourcesCC() {
}

// static
SharedResourcesCC* SharedResourcesCC::GetInstance() {
  // We use LeakySingletonTraits so that we don't race with
  // the tear down of the gl_bindings.
  SharedResourcesCC* instance = Singleton<SharedResourcesCC,
      LeakySingletonTraits<SharedResourcesCC> >::get();
  if (instance->Initialize()) {
    return instance;
  } else {
    instance->Destroy();
    return NULL;
  }
}

bool SharedResourcesCC::Initialize() {
  if (initialized_)
    return true;

  {
    // The following line of code exists soley to disable IO restrictions
    // on this thread long enough to perform the GL bindings.
    // TODO(wjmaclean) Remove this when GL initialisation cleaned up.
    base::ThreadRestrictions::ScopedAllowIO allow_io;
    if (!gfx::GLSurface::InitializeOneOff() ||
        gfx::GetGLImplementation() == gfx::kGLImplementationNone) {
      LOG(ERROR) << "Could not load the GL bindings";
      return false;
    }
  }

  surface_ = gfx::GLSurface::CreateOffscreenGLSurface(false, gfx::Size(1, 1));
  if (!surface_.get()) {
    LOG(ERROR) << "Unable to create offscreen GL surface.";
    return false;
  }

  context_ = gfx::GLContext::CreateGLContext(
      NULL, surface_.get(), gfx::PreferIntegratedGpu);
  if (!context_.get()) {
    LOG(ERROR) << "Unable to create GL context.";
    return false;
  }

  initialized_ = true;
  return true;
}

void SharedResourcesCC::Destroy() {
  context_ = NULL;
  surface_ = NULL;

  initialized_ = false;
}

gfx::ScopedMakeCurrent* SharedResourcesCC::GetScopedMakeCurrent() {
  DCHECK(initialized_);
  if (initialized_)
    return new gfx::ScopedMakeCurrent(context_.get(), surface_.get());
  else
    return NULL;
}

void* SharedResourcesCC::GetDisplay() {
  return surface_->GetDisplay();
}

gfx::GLShareGroup* SharedResourcesCC::GetShareGroup() {
  DCHECK(initialized_);
  return context_->share_group();
}

TextureCC::TextureCC()
    : texture_id_(0),
      flipped_(false) {
}

void TextureCC::SetCanvas(const SkCanvas& canvas,
                          const gfx::Point& origin,
                          const gfx::Size& overall_size) {
  NOTREACHED();
}

void TextureCC::Draw(const ui::TextureDrawParams& params,
                     const gfx::Rect& clip_bounds_in_texture) {
  NOTREACHED();
}

// static
bool CompositorCC::test_context_enabled_ = false;

CompositorCC::CompositorCC(CompositorDelegate* delegate,
                           gfx::AcceleratedWidget widget,
                           const gfx::Size& size)
    : Compositor(delegate, size),
      widget_(widget),
      root_web_layer_(WebKit::WebLayer::create(this)) {
  WebKit::WebLayerTreeView::Settings settings;
  CommandLine* command_line = CommandLine::ForCurrentProcess();
  settings.showFPSCounter =
     command_line->HasSwitch(switches::kUIShowFPSCounter);
  settings.showPlatformLayerTree =
      command_line->HasSwitch(switches::kUIShowLayerTree);
#ifndef WEBCOMPOSITOR_HAS_INITIALIZE
  settings.enableCompositorThread = !!g_compositor_thread;
#endif
  host_ = WebKit::WebLayerTreeView::create(this, root_web_layer_, settings);
  root_web_layer_.setAnchorPoint(WebKit::WebFloatPoint(0.f, 0.f));
  OnWidgetSizeChanged();
}

CompositorCC::~CompositorCC() {
  // There's a cycle between |root_web_layer_| and |host_|, which results in
  // leaking and/or crashing. Explicitly set the root layer to NULL so the cycle
  // is broken.
  host_.setRootLayer(NULL);
}

void CompositorCC::Initialize(bool use_thread) {
  if (use_thread)
    g_compositor_thread = new webkit_glue::WebThreadImpl("Browser Compositor");
#ifdef WEBCOMPOSITOR_HAS_INITIALIZE
  WebKit::WebCompositor::initialize(g_compositor_thread);
#else
  if (use_thread)
    WebKit::WebCompositor::setThread(g_compositor_thread);
#endif
}

void CompositorCC::Terminate() {
#ifdef WEBCOMPOSITOR_HAS_INITIALIZE
  WebKit::WebCompositor::shutdown();
#endif
  DCHECK(g_compositor_thread);
  delete g_compositor_thread;
  g_compositor_thread = NULL;
}

// static
void CompositorCC::EnableTestContextIfNecessary() {
  // TODO: only do this if command line param not set.
  test_context_enabled_ = true;
}

Texture* CompositorCC::CreateTexture() {
  NOTREACHED();
  return NULL;
}

void CompositorCC::Blur(const gfx::Rect& bounds) {
  NOTIMPLEMENTED();
}

void CompositorCC::ScheduleDraw() {
  if (g_compositor_thread)
    host_.composite();
  else
    Compositor::ScheduleDraw();
}

void CompositorCC::OnNotifyStart(bool clear) {
}

void CompositorCC::OnNotifyEnd() {
}

void CompositorCC::OnWidgetSizeChanged() {
  host_.setViewportSize(size());
  root_web_layer_.setBounds(size());
}

void CompositorCC::OnRootLayerChanged() {
  root_web_layer_.removeAllChildren();
  if (root_layer())
    root_web_layer_.addChild(root_layer()->web_layer());
}

void CompositorCC::DrawTree() {
  host_.composite();
}

bool CompositorCC::ReadPixels(SkBitmap* bitmap, const gfx::Rect& bounds) {
  if (bounds.right() > size().width() || bounds.bottom() > size().height())
    return false;
  // Convert to OpenGL coordinates.
  gfx::Point new_origin(bounds.x(),
                        size().height() - bounds.height() - bounds.y());

  bitmap->setConfig(SkBitmap::kARGB_8888_Config,
                    bounds.width(), bounds.height());
  bitmap->allocPixels();
  SkAutoLockPixels lock_image(*bitmap);
  unsigned char* pixels = static_cast<unsigned char*>(bitmap->getPixels());
  if (host_.compositeAndReadback(pixels,
                                 gfx::Rect(new_origin, bounds.size()))) {
    SwizzleRGBAToBGRAAndFlip(pixels, bounds.size());
    return true;
  }
  return false;
}

void CompositorCC::animateAndLayout(double frameBeginTime) {
}

void CompositorCC::applyScrollAndScale(const WebKit::WebSize& scrollDelta,
                                       float scaleFactor) {
}

void CompositorCC::applyScrollDelta(const WebKit::WebSize&) {
}

WebKit::WebGraphicsContext3D* CompositorCC::createContext3D() {
  WebKit::WebGraphicsContext3D* context;
  if (test_context_enabled_) {
    context = new TestWebGraphicsContext3D();
  } else {
    gfx::GLShareGroup* share_group =
        SharedResourcesCC::GetInstance()->GetShareGroup();
    context = new webkit::gpu::WebGraphicsContext3DInProcessImpl(
        widget_, share_group);
  }
  WebKit::WebGraphicsContext3D::Attributes attrs;
  context->initialize(attrs, 0, true);

  CommandLine* command_line = CommandLine::ForCurrentProcess();
  if (!command_line->HasSwitch(switches::kDisableUIVsync)) {
    context->makeContextCurrent();
    gfx::GLContext* gl_context = gfx::GLContext::GetCurrent();
    gl_context->SetSwapInterval(1);
    gl_context->ReleaseCurrent(NULL);
  }

  return context;
}

void CompositorCC::didRebindGraphicsContext(bool success) {
}

void CompositorCC::scheduleComposite() {
  ScheduleDraw();
}

void CompositorCC::notifyNeedsComposite() {
  ScheduleDraw();
}

Compositor* Compositor::Create(CompositorDelegate* owner,
                               gfx::AcceleratedWidget widget,
                               const gfx::Size& size) {
  return new CompositorCC(owner, widget, size);
}

}  // namespace ui
<|endoftext|>


<commit_before><commit_msg>Revert 58093 as an experiment to fix the Cookies test on linux.<commit_after><|endoftext|>


<commit_before>/*
 * Copyright 2007-2021 CM4all GmbH
 * All rights reserved.
 *
 * author: Max Kellermann <mk@cm4all.com>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the
 * distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
 * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "PrometheusExporter.hxx"
#include "PrometheusExporterConfig.hxx"
#include "Instance.hxx"
#include "prometheus/Stats.hxx"
#include "beng-proxy/Control.hxx"
#include "http/Address.hxx"
#include "http/Headers.hxx"
#include "http/IncomingRequest.hxx"
#include "http/ResponseHandler.hxx"
#include "http/GlueClient.hxx"
#include "util/Cancellable.hxx"
#include "util/MimeType.hxx"
#include "istream/ConcatIstream.hxx"
#include "istream/DelayedIstream.hxx"
#include "istream/UnusedHoldPtr.hxx"
#include "istream/istream_catch.hxx"
#include "memory/istream_gb.hxx"
#include "memory/GrowingBuffer.hxx"
#include "stopwatch.hxx"

class LbPrometheusExporter::AppendRequest final
	: public HttpResponseHandler, Cancellable
{
	DelayedIstreamControl &control;

	HttpAddress address{false, "dummy:80", "/"};

	CancellablePointer cancel_ptr;

public:
	AppendRequest(SocketAddress _address,
		      DelayedIstreamControl &_control) noexcept
		:control(_control)
	{
		control.cancel_ptr = *this;

		address.addresses.AddPointer(_address);
	}

	void Start(struct pool &pool, LbInstance &instance) noexcept;

	void Destroy() noexcept {
		this->~AppendRequest();
	}

	void DestroyError(std::exception_ptr error) noexcept {
		auto &_control = control;
		Destroy();
		_control.SetError(std::move(error));
	}

	/* virtual methods from class HttpResponseHandler */
	void OnHttpResponse(http_status_t status, StringMap &&headers,
			    UnusedIstreamPtr body) noexcept override;

	void OnHttpError(std::exception_ptr error) noexcept override {
		DestroyError(std::move(error));
	}

private:
	/* virtual methods from class Cancellable */
	void Cancel() noexcept override {
		cancel_ptr.Cancel();
		Destroy();
	}
};

inline void
LbPrometheusExporter::AppendRequest::Start(struct pool &pool,
					   LbInstance &instance) noexcept
{
	http_request(pool, instance.event_loop,
		     *instance.fs_balancer, {}, {},
		     nullptr,
		     HTTP_METHOD_GET, address, {}, nullptr,
		     *this, cancel_ptr);
}

void
LbPrometheusExporter::AppendRequest::OnHttpResponse(http_status_t status,
						    StringMap &&headers,
						    UnusedIstreamPtr body) noexcept
try {
	if (!http_status_is_success(status))
		throw std::runtime_error("HTTP request not sucessful");

	const char *content_type = headers.Get("content-type");
	if (content_type == nullptr ||
	    GetMimeTypeBase(content_type) != "text/plain")
		throw std::runtime_error("Not text/plain");

	control.Set(std::move(body));
} catch (...) {
	DestroyError(std::current_exception());
}

static std::exception_ptr
CatchCallback(std::exception_ptr, void *) noexcept
{
	// TODO log?
	return {};
}

void
LbPrometheusExporter::HandleRequest(IncomingHttpRequest &request,
				    CancellablePointer &) noexcept
{
	auto &pool = request.pool;

	GrowingBuffer buffer;

	const char *process = "lb";
	if (instance != nullptr)
		Prometheus::Write(buffer, process, instance->GetStats());

	HttpHeaders headers;
	headers.Write("content-type", "text/plain;version=0.0.4");

	auto body = NewConcatIstream(pool,
				     istream_gb_new(pool, std::move(buffer)));

	for (const auto &i : config.load_from_local) {
		// TODO check instance!=nullptr
		auto delayed = istream_delayed_new(pool, instance->event_loop);
		UnusedHoldIstreamPtr hold(pool, std::move(delayed.first));

		auto *ar = NewFromPool<AppendRequest>(pool, i, delayed.second);
		ar->Start(pool, *instance);

		AppendConcatIstream(body,
				    istream_catch_new(pool,
						      std::move(hold),
						      CatchCallback, nullptr));
	}

	request.SendResponse(HTTP_STATUS_OK, std::move(headers),
			     std::move(body));
}
<commit_msg>lb/PrometheusExporter: move code to separate function<commit_after>/*
 * Copyright 2007-2021 CM4all GmbH
 * All rights reserved.
 *
 * author: Max Kellermann <mk@cm4all.com>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the
 * distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
 * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "PrometheusExporter.hxx"
#include "PrometheusExporterConfig.hxx"
#include "Instance.hxx"
#include "prometheus/Stats.hxx"
#include "beng-proxy/Control.hxx"
#include "http/Address.hxx"
#include "http/Headers.hxx"
#include "http/IncomingRequest.hxx"
#include "http/ResponseHandler.hxx"
#include "http/GlueClient.hxx"
#include "util/Cancellable.hxx"
#include "util/MimeType.hxx"
#include "istream/ConcatIstream.hxx"
#include "istream/DelayedIstream.hxx"
#include "istream/UnusedHoldPtr.hxx"
#include "istream/istream_catch.hxx"
#include "memory/istream_gb.hxx"
#include "memory/GrowingBuffer.hxx"
#include "stopwatch.hxx"

class LbPrometheusExporter::AppendRequest final
	: public HttpResponseHandler, Cancellable
{
	DelayedIstreamControl &control;

	HttpAddress address{false, "dummy:80", "/"};

	CancellablePointer cancel_ptr;

public:
	AppendRequest(SocketAddress _address,
		      DelayedIstreamControl &_control) noexcept
		:control(_control)
	{
		control.cancel_ptr = *this;

		address.addresses.AddPointer(_address);
	}

	void Start(struct pool &pool, LbInstance &instance) noexcept;

	void Destroy() noexcept {
		this->~AppendRequest();
	}

	void DestroyError(std::exception_ptr error) noexcept {
		auto &_control = control;
		Destroy();
		_control.SetError(std::move(error));
	}

	/* virtual methods from class HttpResponseHandler */
	void OnHttpResponse(http_status_t status, StringMap &&headers,
			    UnusedIstreamPtr body) noexcept override;

	void OnHttpError(std::exception_ptr error) noexcept override {
		DestroyError(std::move(error));
	}

private:
	/* virtual methods from class Cancellable */
	void Cancel() noexcept override {
		cancel_ptr.Cancel();
		Destroy();
	}
};

inline void
LbPrometheusExporter::AppendRequest::Start(struct pool &pool,
					   LbInstance &instance) noexcept
{
	http_request(pool, instance.event_loop,
		     *instance.fs_balancer, {}, {},
		     nullptr,
		     HTTP_METHOD_GET, address, {}, nullptr,
		     *this, cancel_ptr);
}

void
LbPrometheusExporter::AppendRequest::OnHttpResponse(http_status_t status,
						    StringMap &&headers,
						    UnusedIstreamPtr body) noexcept
try {
	if (!http_status_is_success(status))
		throw std::runtime_error("HTTP request not sucessful");

	const char *content_type = headers.Get("content-type");
	if (content_type == nullptr ||
	    GetMimeTypeBase(content_type) != "text/plain")
		throw std::runtime_error("Not text/plain");

	control.Set(std::move(body));
} catch (...) {
	DestroyError(std::current_exception());
}

static std::exception_ptr
CatchCallback(std::exception_ptr, void *) noexcept
{
	// TODO log?
	return {};
}

static void
WriteStats(GrowingBuffer &buffer, const LbInstance &instance) noexcept
{
	const char *process = "lb";

	Prometheus::Write(buffer, process, instance.GetStats());
}

void
LbPrometheusExporter::HandleRequest(IncomingHttpRequest &request,
				    CancellablePointer &) noexcept
{
	auto &pool = request.pool;

	GrowingBuffer buffer;

	if (instance != nullptr)
		WriteStats(buffer, *instance);

	HttpHeaders headers;
	headers.Write("content-type", "text/plain;version=0.0.4");

	auto body = NewConcatIstream(pool,
				     istream_gb_new(pool, std::move(buffer)));

	for (const auto &i : config.load_from_local) {
		// TODO check instance!=nullptr
		auto delayed = istream_delayed_new(pool, instance->event_loop);
		UnusedHoldIstreamPtr hold(pool, std::move(delayed.first));

		auto *ar = NewFromPool<AppendRequest>(pool, i, delayed.second);
		ar->Start(pool, *instance);

		AppendConcatIstream(body,
				    istream_catch_new(pool,
						      std::move(hold),
						      CatchCallback, nullptr));
	}

	request.SendResponse(HTTP_STATUS_OK, std::move(headers),
			     std::move(body));
}
<|endoftext|>


<commit_before><commit_msg>fix gtk3 build<commit_after><|endoftext|>


<commit_before>
/****************************************************************************
** Copyright (c) 2006 - 2011, the LibQxt project.
** See the Qxt AUTHORS file for a list of authors and copyright holders.
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**     * Redistributions of source code must retain the above copyright
**       notice, this list of conditions and the following disclaimer.
**     * Redistributions in binary form must reproduce the above copyright
**       notice, this list of conditions and the following disclaimer in the
**       documentation and/or other materials provided with the distribution.
**     * Neither the name of the LibQxt project nor the
**       names of its contributors may be used to endorse or promote products
**       derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
** <http://libqxt.org>  <foundation@libqxt.org>
*****************************************************************************/

#include "qxtsqlthreadmanager.h"
#include <QThread>
#include <QSqlDriver>
#include <QSqlQuery>
#include <QSqlError>
#include <QDebug>

/*!
\class QxtSqlThreadManager

\inmodule QxtSql

\brief The QxtSqlThreadManager class provides a thread-safe means of using a QSqlDatabase connection

All use of a given QSqlDatabase must be performed within the thread which
created it. This class makes management of thread-specific instances of your
QSqlDatabase relatively painless.

Main thread:
\code
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
db.setDatabase("somedatabasename");
db.setUser("johndoe");
...
if(!db.open())
    throw an_exception();
\endcode

Worker thread:
\code
QSqlQuery myQuery(QxtSqlThreadManager::connection());
myQuery.exec(...);
\endcode

The connection() method will obtain a reference to a QSqlDatabase assigned to
the current thread, creating one as necessary. When the thread exits, the
connection and all other resources are cleaned up automatically.

The QxtSqlThreadManager's constructor is private and never accessed directly
by client code. Use the static manager() method if any of the other members
or properties need to be referenced.

\warning Care must be taken to avoid passing references to any of the QSql
objects to other threads. Use of the QxtSqlPackage class may help in this
regard.

\warning Although you may specify a name for the primary thread's master
connection, this class only manages a single set of connections and is
typically used with the default connection (omitting the name).
*/

/*!
\internal

This is the actual thread-storage object. Since it is a static member, it
will have global allocation scope.
*/
QThreadStorage<QxtSqlThreadManager*> QxtSqlThreadManager::connections;

/*!
\internal

Constructs a connection for the calling thread. The resulting class must
never be accessed from any other thread than the one for which it was
constructed. The \a masterName must reference an existing database
connection which is already open.
*/
QxtSqlThreadManager::QxtSqlThreadManager(const QString &masterName)
{
    // Build a name for the new connection
    name = QString("$qxt$tc_%1$%2")
	.arg(QThread::currentThreadId())
	.arg(masterName);
    // Clone the primary thread's connection
    Q_ASSERT(QSqlDatabase::contains(masterName));
    Q_ASSERT(QSqlDatabase::database(masterName).isOpen() == true);
    QSqlDatabase conn = QSqlDatabase::cloneDatabase(
	    QSqlDatabase::database(masterName), name);
    // Open the connection (should not fail but ...)
    if(!conn.open())
	qWarning() << Q_FUNC_INFO
	    << "Failed to open connection to database" << conn.databaseName()
	    << ", error: " << conn.lastError().text();
    qDebug() << "Constructed database connection" << name;
}

/*! Destroys the connection being managed
*/
QxtSqlThreadManager::~QxtSqlThreadManager()
{
    // Close the database if it's currently open
    {
	// Scoped so our local copy doesn't exist during removal
	QSqlDatabase conn = QSqlDatabase::database(this->name);
	if(conn.isOpen())
	    conn.close();
    }
    QSqlDatabase::removeDatabase(this->name);
    qDebug() << "Removed database connection" << this->name;
}

/*! Returns a pointer to the QxtSqlThreadManager for the current (calling)
 *  thread. A manager will be automatically created if one does not
 *  already exist. If the database connection being managed is not the
 *  default connection, it's name must be supplied as the \a masterName
 *  parameter on every invokation so it will be available in cases where
 *  it is needed.
 *  The pointer returned will never be \i null.
 *  \warning This pointer must never be deleted. If the manager is deleted,
 *  the next time the pointer is retrieved it will reference a dangling
 *  pointer and memory corruption is certain. Likewise, once the thread exits,
 *  the program will crash. \bold {You have been warned!}
 */
QxtSqlThreadManager * QxtSqlThreadManager::manager(const QString &masterName)
{
    if(!connections.hasLocalData())
	connections.setLocalData(new QxtSqlThreadManager(masterName));
    return connections.localData();
}

/*! Selects a new database name \a dbname for the connection. If the
 *  connection is already using the named database, nothing happens.
 *  For those database backends which do not support the \c USE statement,
 *  the connection will be closed and reopened as needed. This name is \i not
 *  the same as the connection's name.
 *  \warning Every effort is made to avoid leaving the connection in a closed
 *  (or otherwise unusable state) but all bets are off when a non-existant
 *  database name is requested.
 */
void QxtSqlThreadManager::selectDatabase(const QString &dbname)
{
    QSqlDatabase conn = database();
    if(conn.isOpen()){
	// We're already open -- check to see if we can avoid a close
	if(conn.databaseName() == dbname)
	    return; // No need to do anything regardless
	if(conn.driverName().startsWith("QMYSQL", Qt::CaseInsensitive)){
	    // Database supports "USE" -- so do it that way
	    QSqlQuery qry(conn);
	    if(!qry.exec("USE "+conn.driver()->escapeIdentifier(dbname,
			    QSqlDriver::TableName)))
		qWarning() << Q_FUNC_INFO << "Failed to change database to"
		    << dbname << ", error:" << qry.lastError().text();
	    // Set name so we'll see it next time (then we're done here)
	    conn.setDatabaseName(dbname);
	    return;
	}
	// Couldn't swap names on the current connection -- so close it
	conn.close();
    }
    // Reaching here means we've got to set the database name & open it
    conn.setDatabaseName(dbname);
    if(!conn.open())
	qWarning() << Q_FUNC_INFO
	    << "Failed to open connection to database" << dbname
	    << ", error: " << conn.lastError().text();
}

/*!
\fn  QString QxtSqlThreadManager::connectionName() const
\brief Returns the name of the managed QSqlDatabase connection.
*/

/*!
\fn  QSqlDatabase QxtSqlThreadManager::database() const
\brief Returns the QSqlDatabase object being managed by the
QxtSqlThreadManager class.
*/

/*!
\fn QSqlDatabase QxtSqlThreadManager::connection(const QString &masterName)
\brief Returns a QSqlDatabase connection for the current thread.
This is usually used as the parameter when constructing a QSqlQuery within
a worker thread. If the database connection being managed is not the
default connection, it's name must be supplied as the \a masterName
parameter on every invokation.
*/
<commit_msg>Cast the thread's ID in QxtSqlThreadManager's constructor to avoid MSVC complaint.<commit_after>
/****************************************************************************
** Copyright (c) 2006 - 2011, the LibQxt project.
** See the Qxt AUTHORS file for a list of authors and copyright holders.
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are met:
**     * Redistributions of source code must retain the above copyright
**       notice, this list of conditions and the following disclaimer.
**     * Redistributions in binary form must reproduce the above copyright
**       notice, this list of conditions and the following disclaimer in the
**       documentation and/or other materials provided with the distribution.
**     * Neither the name of the LibQxt project nor the
**       names of its contributors may be used to endorse or promote products
**       derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
** <http://libqxt.org>  <foundation@libqxt.org>
*****************************************************************************/

#include "qxtsqlthreadmanager.h"
#include <QThread>
#include <QSqlDriver>
#include <QSqlQuery>
#include <QSqlError>
#include <QDebug>

/*!
\class QxtSqlThreadManager

\inmodule QxtSql

\brief The QxtSqlThreadManager class provides a thread-safe means of using a QSqlDatabase connection

All use of a given QSqlDatabase must be performed within the thread which
created it. This class makes management of thread-specific instances of your
QSqlDatabase relatively painless.

Main thread:
\code
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
db.setDatabase("somedatabasename");
db.setUser("johndoe");
...
if(!db.open())
    throw an_exception();
\endcode

Worker thread:
\code
QSqlQuery myQuery(QxtSqlThreadManager::connection());
myQuery.exec(...);
\endcode

The connection() method will obtain a reference to a QSqlDatabase assigned to
the current thread, creating one as necessary. When the thread exits, the
connection and all other resources are cleaned up automatically.

The QxtSqlThreadManager's constructor is private and never accessed directly
by client code. Use the static manager() method if any of the other members
or properties need to be referenced.

\warning Care must be taken to avoid passing references to any of the QSql
objects to other threads. Use of the QxtSqlPackage class may help in this
regard.

\warning Although you may specify a name for the primary thread's master
connection, this class only manages a single set of connections and is
typically used with the default connection (omitting the name).
*/

/*!
\internal

This is the actual thread-storage object. Since it is a static member, it
will have global allocation scope.
*/
QThreadStorage<QxtSqlThreadManager*> QxtSqlThreadManager::connections;

/*!
\internal

Constructs a connection for the calling thread. The resulting class must
never be accessed from any other thread than the one for which it was
constructed. The \a masterName must reference an existing database
connection which is already open.
*/
QxtSqlThreadManager::QxtSqlThreadManager(const QString &masterName)
{
    // Build a name for the new connection
    name = QString("$qxt$tc_%1$%2")
	.arg((long)(void*)QThread::currentThreadId())
	.arg(masterName);
    // Clone the primary thread's connection
    Q_ASSERT(QSqlDatabase::contains(masterName));
    Q_ASSERT(QSqlDatabase::database(masterName).isOpen() == true);
    QSqlDatabase conn = QSqlDatabase::cloneDatabase(
	    QSqlDatabase::database(masterName), name);
    // Open the connection (should not fail but ...)
    if(!conn.open())
	qWarning() << Q_FUNC_INFO
	    << "Failed to open connection to database" << conn.databaseName()
	    << ", error: " << conn.lastError().text();
    qDebug() << "Constructed database connection" << name;
}

/*! Destroys the connection being managed
*/
QxtSqlThreadManager::~QxtSqlThreadManager()
{
    // Close the database if it's currently open
    {
	// Scoped so our local copy doesn't exist during removal
	QSqlDatabase conn = QSqlDatabase::database(this->name);
	if(conn.isOpen())
	    conn.close();
    }
    QSqlDatabase::removeDatabase(this->name);
    qDebug() << "Removed database connection" << this->name;
}

/*! Returns a pointer to the QxtSqlThreadManager for the current (calling)
 *  thread. A manager will be automatically created if one does not
 *  already exist. If the database connection being managed is not the
 *  default connection, it's name must be supplied as the \a masterName
 *  parameter on every invokation so it will be available in cases where
 *  it is needed.
 *  The pointer returned will never be \i null.
 *  \warning This pointer must never be deleted. If the manager is deleted,
 *  the next time the pointer is retrieved it will reference a dangling
 *  pointer and memory corruption is certain. Likewise, once the thread exits,
 *  the program will crash. \bold {You have been warned!}
 */
QxtSqlThreadManager * QxtSqlThreadManager::manager(const QString &masterName)
{
    if(!connections.hasLocalData())
	connections.setLocalData(new QxtSqlThreadManager(masterName));
    return connections.localData();
}

/*! Selects a new database name \a dbname for the connection. If the
 *  connection is already using the named database, nothing happens.
 *  For those database backends which do not support the \c USE statement,
 *  the connection will be closed and reopened as needed. This name is \i not
 *  the same as the connection's name.
 *  \warning Every effort is made to avoid leaving the connection in a closed
 *  (or otherwise unusable state) but all bets are off when a non-existant
 *  database name is requested.
 */
void QxtSqlThreadManager::selectDatabase(const QString &dbname)
{
    QSqlDatabase conn = database();
    if(conn.isOpen()){
	// We're already open -- check to see if we can avoid a close
	if(conn.databaseName() == dbname)
	    return; // No need to do anything regardless
	if(conn.driverName().startsWith("QMYSQL", Qt::CaseInsensitive)){
	    // Database supports "USE" -- so do it that way
	    QSqlQuery qry(conn);
	    if(!qry.exec("USE "+conn.driver()->escapeIdentifier(dbname,
			    QSqlDriver::TableName)))
		qWarning() << Q_FUNC_INFO << "Failed to change database to"
		    << dbname << ", error:" << qry.lastError().text();
	    // Set name so we'll see it next time (then we're done here)
	    conn.setDatabaseName(dbname);
	    return;
	}
	// Couldn't swap names on the current connection -- so close it
	conn.close();
    }
    // Reaching here means we've got to set the database name & open it
    conn.setDatabaseName(dbname);
    if(!conn.open())
	qWarning() << Q_FUNC_INFO
	    << "Failed to open connection to database" << dbname
	    << ", error: " << conn.lastError().text();
}

/*!
\fn  QString QxtSqlThreadManager::connectionName() const
\brief Returns the name of the managed QSqlDatabase connection.
*/

/*!
\fn  QSqlDatabase QxtSqlThreadManager::database() const
\brief Returns the QSqlDatabase object being managed by the
QxtSqlThreadManager class.
*/

/*!
\fn QSqlDatabase QxtSqlThreadManager::connection(const QString &masterName)
\brief Returns a QSqlDatabase connection for the current thread.
This is usually used as the parameter when constructing a QSqlQuery within
a worker thread. If the database connection being managed is not the
default connection, it's name must be supplied as the \a masterName
parameter on every invokation.
*/
<|endoftext|>


<commit_before>/*
    Copyright (C) 2016 Volker Krause <vkrause@kde.org>

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

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

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "syntaxhighlighter.h"
#include "format.h"

#include <QDebug>

using namespace SyntaxHighlighting;

SyntaxHighlighter::SyntaxHighlighter(QObject* parent) :
    QSyntaxHighlighter(parent)
{
}

SyntaxHighlighter::~SyntaxHighlighter()
{
}

void SyntaxHighlighter::highlightBlock(const QString& text)
{
    if (currentBlock().position() == 0)
        reset();
    highlightLine(text);
}

void SyntaxHighlighter::setFormat(int offset, int length, const SyntaxHighlighting::Format& format)
{
    if (format.isNormal(theme()) || offset == length)
        return;

    QTextCharFormat tf;
    if (format.hasColor(theme()))
        tf.setForeground(format.color(theme()));
    if (format.hasBackgroundColor(theme()))
        tf.setBackground(format.backgroundColor(theme()));

    if (format.isBold(theme()))
        tf.setFontWeight(QFont::Bold);
    if (format.isItalic(theme()))
        tf.setFontItalic(true);
    if (format.isUnderline(theme()))
        tf.setFontUnderline(true);
    if (format.isStrikeThrough(theme()))
        tf.setFontStrikeOut(true);

    QSyntaxHighlighter::setFormat(offset, length, tf);
}
<commit_msg>Fix broken empty range test in QSyntaxHighlighter<commit_after>/*
    Copyright (C) 2016 Volker Krause <vkrause@kde.org>

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

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

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "syntaxhighlighter.h"
#include "format.h"

#include <QDebug>

using namespace SyntaxHighlighting;

SyntaxHighlighter::SyntaxHighlighter(QObject* parent) :
    QSyntaxHighlighter(parent)
{
}

SyntaxHighlighter::~SyntaxHighlighter()
{
}

void SyntaxHighlighter::highlightBlock(const QString& text)
{
    if (currentBlock().position() == 0)
        reset();
    highlightLine(text);
}

void SyntaxHighlighter::setFormat(int offset, int length, const SyntaxHighlighting::Format& format)
{
    if (format.isNormal(theme()) || length == 0)
        return;

    QTextCharFormat tf;
    if (format.hasColor(theme()))
        tf.setForeground(format.color(theme()));
    if (format.hasBackgroundColor(theme()))
        tf.setBackground(format.backgroundColor(theme()));

    if (format.isBold(theme()))
        tf.setFontWeight(QFont::Bold);
    if (format.isItalic(theme()))
        tf.setFontItalic(true);
    if (format.isUnderline(theme()))
        tf.setFontUnderline(true);
    if (format.isStrikeThrough(theme()))
        tf.setFontStrikeOut(true);

    QSyntaxHighlighter::setFormat(offset, length, tf);
}
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
 *     Copyright 2010 Couchbase, Inc
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */

#include "config.h"

#ifdef _MSC_VER
#define alarm(a)
#endif

#include <algorithm>
#include <cassert>
#include <vector>

#include "atomic.h"
#include "threadtests.h"

const size_t numThreads    = 100;
const size_t numIterations = 1000;

class AtomicIntTest : public Generator<int> {
public:

    AtomicIntTest(int start=0) : i(start) {}

    int operator()() {
        for (size_t j = 0; j < numIterations-1; j++) {
           ++i;
        }
        return ++i;
    }

    int latest(void) { return i.load(); }

private:
    AtomicValue<int> i;
};

static void testAtomicInt() {
    AtomicIntTest intgen;
    // Run this test with 100 concurrent threads.
    std::vector<int> r(getCompletedThreads<int>(numThreads, &intgen));

    // We should have 100 distinct numbers.
    std::sort(r.begin(), r.end());
    std::unique(r.begin(), r.end());
    assert(r.size() == numThreads);

    // And the last number should be (numThreads * numIterations)
    assert(intgen.latest() == (numThreads * numIterations));
}

static void testSetIfLess() {
    AtomicValue<int> x;

    x.store(842);
    atomic_setIfLess(x, 924);
    assert(x.load() == 842);
    atomic_setIfLess(x, 813);
    assert(x.load() == 813);
}

static void testSetIfBigger() {
    AtomicValue<int> x;

    x.store(842);
    atomic_setIfBigger(x, 13);
    assert(x.load() == 842);
    atomic_setIfBigger(x, 924);
    assert(x.load() == 924);
}

int main() {
    alarm(60);
    testAtomicInt();
    testSetIfLess();
    testSetIfBigger();
}
<commit_msg>Test atomic.compare_exchange_strong<commit_after>/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
 *     Copyright 2010 Couchbase, Inc
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */

#include "config.h"

#ifdef _MSC_VER
#define alarm(a)
#endif

#include <algorithm>
#include <cassert>
#include <vector>

#include "atomic.h"
#include "threadtests.h"

const size_t numThreads    = 100;
const size_t numIterations = 1000;

class AtomicIntTest : public Generator<int> {
public:

    AtomicIntTest(int start=0) : i(start) {}

    int operator()() {
        for (size_t j = 0; j < numIterations-1; j++) {
           ++i;
        }
        return ++i;
    }

    int latest(void) { return i.load(); }

private:
    AtomicValue<int> i;
};

static void testAtomicInt() {
    AtomicIntTest intgen;
    // Run this test with 100 concurrent threads.
    std::vector<int> r(getCompletedThreads<int>(numThreads, &intgen));

    // We should have 100 distinct numbers.
    std::sort(r.begin(), r.end());
    std::unique(r.begin(), r.end());
    assert(r.size() == numThreads);

    // And the last number should be (numThreads * numIterations)
    assert(intgen.latest() == (numThreads * numIterations));
}

static void testSetIfLess() {
    AtomicValue<int> x;

    x.store(842);
    atomic_setIfLess(x, 924);
    assert(x.load() == 842);
    atomic_setIfLess(x, 813);
    assert(x.load() == 813);
}

static void testSetIfBigger() {
    AtomicValue<int> x;

    x.store(842);
    atomic_setIfBigger(x, 13);
    assert(x.load() == 842);
    atomic_setIfBigger(x, 924);
    assert(x.load() == 924);
}

int testAtomicCompareExchangeStrong(void) {
    AtomicValue<bool> x(true);
    bool expected = false;

    int returncode = 0;

    if (x.compare_exchange_strong(expected, false)) {
        std::cerr << "ERROR. this is supposed to be true "
                  << "and we're comparing with false" << std::endl;
        ++returncode;
    }

    if (!x) {
        std::cerr << "Expected value to be updated" << std::endl;
        ++returncode;
    }

    if (!expected) {
        std::cerr << "Expected should be set from compare_exchange_strong"
                  << std::endl;
        ++returncode;
    }

    if (!x.compare_exchange_strong(expected, false)) {
        std::cerr << "ERROR. this is supposed to be true "
                  << "and we're comparing with true" << std::endl;
        ++returncode;
    }

    if (x) {
        std::cerr << "Expected value to be updated" << std::endl;
        ++returncode;
    }

    return returncode;
}

int main() {
    alarm(60);
    testAtomicInt();
    testSetIfLess();
    testSetIfBigger();
    return testAtomicCompareExchangeStrong();
}
<|endoftext|>