<commit_before>#include <iostream>
#include "timing/Chrono.h"
#include "CPUBase.h"
#include "opcode.h"
#include "util.h"

namespace avrel
{
    CPUBase::CPUBase(ROM &rom_, RAM &ram_, int frequency_)
        : rom(rom_), ram(ram_), frequency(frequency_), cycles(0)
    {
        reset();
    }

    void CPUBase::reset()
    {
        rom.jumpTo(0);
        I = T = H = S = V = N = Z = C = false;
        unsigned int i;
        for (i=0; i<REGISTERS_SIZE; i++) {
            registers[i] = 0;
        }
    }

    int CPUBase::readData(unsigned int addr)
    {
        switch (addr) {
            case SREG:
                return getSreg();
                break;
            case SPL:
                return SP&0xff;
                break;
            case SPH:
                return (SP>>8)&0xff;
                break;
        }

        if (addr < REGISTERS_SIZE) {
            return registers[addr];
        } else {
            addr -= REGISTERS_SIZE;
            return ram.readByte(addr);
        }
    }

    void CPUBase::writeData(unsigned int addr, int value)
    {
        switch (addr) {
            case SREG:
                setSreg(value);
                break;
            case SPL:
                SP = (SP&0xff00)|value;
                break;
            case SPH:
                SP = (SP&0x00ff)|(value<<8);
                break;
        }

        if (addr < sizeof(registers)) {
            registers[addr] = value;
            if (addr == PORTB) {
                printf("PORTB: %02x\n", value);
            }
        } else {
            addr -= REGISTERS_SIZE;
            ram.writeByte(addr, value);
        }
    }

    void CPUBase::setSreg(int value)
    {
        I = (value>>7)&1;
        T = (value>>6)&1;
        H = (value>>5)&1;
        S = (value>>4)&1;
        V = (value>>3)&1;
        N = (value>>2)&1;
        Z = (value>>1)&1;
        C = (value>>0)&1;
    }

    int CPUBase::getSreg()
    {
        return
            ((I ? 1 : 0)<<7) |
            ((T ? 1 : 0)<<6) |
            ((H ? 1 : 0)<<5) |
            ((S ? 1 : 0)<<4) |
            ((V ? 1 : 0)<<3) |
            ((N ? 1 : 0)<<2) |
            ((Z ? 1 : 0)<<1) |
            ((C ? 1 : 0)<<0);
    }

    // Utils

    void CPUBase::pushByte(int byte)
    {
        ram.writeByte(SP--, byte);
    }

    void CPUBase::pushWord(int word)
    {
        ram.writeWord(SP, word);
        SP-=2;
    }

    void CPUBase::setFlags(int A, int B, int R, bool carry)
    {
        int A7 = GETBIT(A,7);
        int B7 = GETBIT(B,7);
        int R7 = GETBIT(R,7);
        int A3 = GETBIT(A,3);
        int B3 = GETBIT(B,3);
        int R3 = GETBIT(R,3);

        H = ((!A3) && B3)
            || (B3 && R3)
            || (R3 && (!A3));

        V = (A7 && (!B7) && (!R7))
            || ((!A7) && B7 && R7);

        C = ((!A7) && (B7))
            || (B7 && R7)
            || (R7 && (!A7));

        Z = (R==0) && (carry ? Z : true);
        N = GETBIT(A,7);
        S = N ^ V;
    }

    // Opcodes

    void CPUBase::jmp(int addr)
    {
        OPCODE_DEBUG("jmp %x\n", addr);
        rom.jumpTo(addr);
    }

    void CPUBase::call(int addr)
    {
        OPCODE_DEBUG("call %x\n", addr);
        pushWord(rom.getPosition());
        rom.jumpTo(addr);
    }

    void CPUBase::eor(int r, int d)
    {
        OPCODE_DEBUG("eor r%d, r%d\n", r, d);
        R[d] = R[r] ^ R[d];
        V = 0;
        N = (R[d]>>7)&1;
        S = V^N;
        Z = (R[d] == 0);
    }

    void CPUBase::out(int r, int A)
    {
        OPCODE_DEBUG("out r%d, %x\n", r, A);
        writeData(A, R[r]);
    }

    void CPUBase::sts(int r, int A)
    {
        OPCODE_DEBUG("sts r%d, %x\n", r, A);
        writeData(A, R[r]);
    }

    void CPUBase::in(int r, int A)
    {
        OPCODE_DEBUG("in r%d, %x\n", r, A);
        R[r] = readData(A);
    }

    void CPUBase::ldi(int d, int K)
    {
        OPCODE_DEBUG("ldi r%d, %x\n", d, K);
        R[d] = K;
    }

    void CPUBase::cli()
    {
        OPCODE_DEBUG("cli\n");
        I = false;
    }

    void CPUBase::sei()
    {
        OPCODE_DEBUG("sei\n");
        I = true;
    }

    void CPUBase::sbi(int A, int b)
    {
        OPCODE_DEBUG("sbi %x, %d\n", A, b);
        int value = readData(A);
        value |= (1<<b);
        writeData(A, value);
    }

    void CPUBase::cbi(int A, int b)
    {
        OPCODE_DEBUG("cbi %x, %d\n", A, b);
        int value = readData(A);
        value &= ~(1<<b);
        writeData(A, value);
    }

    void CPUBase::subi(int d, int K)
    {
        OPCODE_DEBUG("subi r%d, %x\n", d, K);
        int old = R[d];
        R[d] -= K;
        setFlags(old, K, R[d]);
    }

    void CPUBase::sbci(int d, int K)
    {
        OPCODE_DEBUG("sbci r%d, %x\n", d, K);
        int old = R[d];
        R[d] -= K + (C ? 1 : 0);
        setFlags(old, K, R[d]);
    }

    bool CPUBase::brne(int k)
    {
        OPCODE_DEBUG("brne %d\n", k);

        if (!Z) {
            rom.jumpRelative(k);
            return true;
        } else {
            return false;
        }
    }

    void CPUBase::rjmp(int k)
    {
        OPCODE_DEBUG("rjmp %d\n", k);
        rom.jumpRelative(k);
    }

    void CPUBase::nop()
    {
        OPCODE_DEBUG("nop\n");
    }

    void CPUBase::cpi(int d, int K)
    {
        OPCODE_DEBUG("cpi r%d, %d\n", d, K);
        setFlags(R[d], K, R[d]);
    }

    void CPUBase::cpc(int d, int r)
    {
        OPCODE_DEBUG("cpc r%d, r%d\n", d, r);
        setFlags(R[d], R[r], R[d]);
    }

    // X Y & Z

    void CPUBase::setX(int value)
    {
        R[27] = (value>>8)&0xff;
        R[26] = (value>>0)&0xff;
    }

    void CPUBase::setY(int value)
    {
        R[29] = (value>>8)&0xff;
        R[28] = (value>>0)&0xff;
    }

    void CPUBase::setZ(int value)
    {
        R[31] = (value>>8)&0xff;
        R[30] = (value>>0)&0xff;
    }

    int CPUBase::getX()
    {
        return (R[27]<<8)|R[26];
    }

    int CPUBase::getY()
    {
        return (R[29]<<8)|R[28];
    }

    int CPUBase::getZ()
    {
        return (R[31]<<8)|R[30];
    }
}
<commit_msg>Fixing N<commit_after>#include <iostream>
#include "timing/Chrono.h"
#include "CPUBase.h"
#include "opcode.h"
#include "util.h"

namespace avrel
{
    CPUBase::CPUBase(ROM &rom_, RAM &ram_, int frequency_)
        : rom(rom_), ram(ram_), frequency(frequency_), cycles(0)
    {
        reset();
    }

    void CPUBase::reset()
    {
        rom.jumpTo(0);
        I = T = H = S = V = N = Z = C = false;
        unsigned int i;
        for (i=0; i<REGISTERS_SIZE; i++) {
            registers[i] = 0;
        }
    }

    int CPUBase::readData(unsigned int addr)
    {
        switch (addr) {
            case SREG:
                return getSreg();
                break;
            case SPL:
                return SP&0xff;
                break;
            case SPH:
                return (SP>>8)&0xff;
                break;
        }

        if (addr < REGISTERS_SIZE) {
            return registers[addr];
        } else {
            addr -= REGISTERS_SIZE;
            return ram.readByte(addr);
        }
    }

    void CPUBase::writeData(unsigned int addr, int value)
    {
        switch (addr) {
            case SREG:
                setSreg(value);
                break;
            case SPL:
                SP = (SP&0xff00)|value;
                break;
            case SPH:
                SP = (SP&0x00ff)|(value<<8);
                break;
        }

        if (addr < sizeof(registers)) {
            registers[addr] = value;
            if (addr == PORTB) {
                printf("PORTB: %02x\n", value);
            }
        } else {
            addr -= REGISTERS_SIZE;
            ram.writeByte(addr, value);
        }
    }

    void CPUBase::setSreg(int value)
    {
        I = (value>>7)&1;
        T = (value>>6)&1;
        H = (value>>5)&1;
        S = (value>>4)&1;
        V = (value>>3)&1;
        N = (value>>2)&1;
        Z = (value>>1)&1;
        C = (value>>0)&1;
    }

    int CPUBase::getSreg()
    {
        return
            ((I ? 1 : 0)<<7) |
            ((T ? 1 : 0)<<6) |
            ((H ? 1 : 0)<<5) |
            ((S ? 1 : 0)<<4) |
            ((V ? 1 : 0)<<3) |
            ((N ? 1 : 0)<<2) |
            ((Z ? 1 : 0)<<1) |
            ((C ? 1 : 0)<<0);
    }

    // Utils

    void CPUBase::pushByte(int byte)
    {
        ram.writeByte(SP--, byte);
    }

    void CPUBase::pushWord(int word)
    {
        ram.writeWord(SP, word);
        SP-=2;
    }

    void CPUBase::setFlags(int A, int B, int R, bool carry)
    {
        int A7 = GETBIT(A,7);
        int B7 = GETBIT(B,7);
        int R7 = GETBIT(R,7);
        int A3 = GETBIT(A,3);
        int B3 = GETBIT(B,3);
        int R3 = GETBIT(R,3);

        H = ((!A3) && B3)
            || (B3 && R3)
            || (R3 && (!A3));

        V = (A7 && (!B7) && (!R7))
            || ((!A7) && B7 && R7);

        C = ((!A7) && (B7))
            || (B7 && R7)
            || (R7 && (!A7));

        Z = (R==0) && (carry ? Z : true);
        N = GETBIT(R,7);
        S = N ^ V;
    }

    // Opcodes

    void CPUBase::jmp(int addr)
    {
        OPCODE_DEBUG("jmp %x\n", addr);
        rom.jumpTo(addr);
    }

    void CPUBase::call(int addr)
    {
        OPCODE_DEBUG("call %x\n", addr);
        pushWord(rom.getPosition());
        rom.jumpTo(addr);
    }

    void CPUBase::eor(int r, int d)
    {
        OPCODE_DEBUG("eor r%d, r%d\n", r, d);
        R[d] = R[r] ^ R[d];
        V = 0;
        N = (R[d]>>7)&1;
        S = V^N;
        Z = (R[d] == 0);
    }

    void CPUBase::out(int r, int A)
    {
        OPCODE_DEBUG("out r%d, %x\n", r, A);
        writeData(A, R[r]);
    }

    void CPUBase::sts(int r, int A)
    {
        OPCODE_DEBUG("sts r%d, %x\n", r, A);
        writeData(A, R[r]);
    }

    void CPUBase::in(int r, int A)
    {
        OPCODE_DEBUG("in r%d, %x\n", r, A);
        R[r] = readData(A);
    }

    void CPUBase::ldi(int d, int K)
    {
        OPCODE_DEBUG("ldi r%d, %x\n", d, K);
        R[d] = K;
    }

    void CPUBase::cli()
    {
        OPCODE_DEBUG("cli\n");
        I = false;
    }

    void CPUBase::sei()
    {
        OPCODE_DEBUG("sei\n");
        I = true;
    }

    void CPUBase::sbi(int A, int b)
    {
        OPCODE_DEBUG("sbi %x, %d\n", A, b);
        int value = readData(A);
        value |= (1<<b);
        writeData(A, value);
    }

    void CPUBase::cbi(int A, int b)
    {
        OPCODE_DEBUG("cbi %x, %d\n", A, b);
        int value = readData(A);
        value &= ~(1<<b);
        writeData(A, value);
    }

    void CPUBase::subi(int d, int K)
    {
        OPCODE_DEBUG("subi r%d, %x\n", d, K);
        int old = R[d];
        R[d] -= K;
        setFlags(old, K, R[d]);
    }

    void CPUBase::sbci(int d, int K)
    {
        OPCODE_DEBUG("sbci r%d, %x\n", d, K);
        int old = R[d];
        R[d] -= K + (C ? 1 : 0);
        setFlags(old, K, R[d]);
    }

    bool CPUBase::brne(int k)
    {
        OPCODE_DEBUG("brne %d\n", k);

        if (!Z) {
            rom.jumpRelative(k);
            return true;
        } else {
            return false;
        }
    }

    void CPUBase::rjmp(int k)
    {
        OPCODE_DEBUG("rjmp %d\n", k);
        rom.jumpRelative(k);
    }

    void CPUBase::nop()
    {
        OPCODE_DEBUG("nop\n");
    }

    void CPUBase::cpi(int d, int K)
    {
        OPCODE_DEBUG("cpi r%d, %d\n", d, K);
        setFlags(R[d], K, R[d]);
    }

    void CPUBase::cpc(int d, int r)
    {
        OPCODE_DEBUG("cpc r%d, r%d\n", d, r);
        setFlags(R[d], R[r], R[d]);
    }

    // X Y & Z

    void CPUBase::setX(int value)
    {
        R[27] = (value>>8)&0xff;
        R[26] = (value>>0)&0xff;
    }

    void CPUBase::setY(int value)
    {
        R[29] = (value>>8)&0xff;
        R[28] = (value>>0)&0xff;
    }

    void CPUBase::setZ(int value)
    {
        R[31] = (value>>8)&0xff;
        R[30] = (value>>0)&0xff;
    }

    int CPUBase::getX()
    {
        return (R[27]<<8)|R[26];
    }

    int CPUBase::getY()
    {
        return (R[29]<<8)|R[28];
    }

    int CPUBase::getZ()
    {
        return (R[31]<<8)|R[30];
    }
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: dp_gui_service.cxx,v $
 *
 *  $Revision: 1.18 $
 *
 *  last change: $Author: ihi $ $Date: 2007-08-20 13:49:38 $
 *
 *  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_desktop.hxx"

#include "dp_gui_shared.hxx"
#include "dp_gui.h"
#include "cppuhelper/implbase2.hxx"
#include "cppuhelper/implementationentry.hxx"
#include "unotools/configmgr.hxx"
#include "comphelper/servicedecl.hxx"
#include "comphelper/unwrapargs.hxx"
#include <i18npool/mslangid.hxx>
#include "vcl/svapp.hxx"
#include "vcl/msgbox.hxx"
#include "com/sun/star/lang/XServiceInfo.hpp"
#include "com/sun/star/task/XJobExecutor.hpp"
#include "com/sun/star/ui/dialogs/XAsynchronousExecutableDialog.hpp"

#include "boost/bind.hpp"
#include "license_dialog.hxx"

using namespace ::dp_misc;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;

using ::rtl::OUString;

namespace css = ::com::sun::star;
namespace dp_gui {

//==============================================================================
class MyApp : public Application, private boost::noncopyable
{
public:
    MyApp();
    virtual ~MyApp();

    // Application
    virtual void Main();
};

//______________________________________________________________________________
MyApp::~MyApp()
{
}

//______________________________________________________________________________
MyApp::MyApp()
{
}

//______________________________________________________________________________
void MyApp::Main()
{
}

//##############################################################################

namespace
{
    struct ProductName
        : public rtl::Static< String, ProductName > {};
    struct Version
        : public rtl::Static< String, Version > {};
    struct AboutBoxVersion
        : public rtl::Static< String, AboutBoxVersion > {};
    struct Extension
        : public rtl::Static< String, Extension > {};
}

void ReplaceProductNameHookProc( String& rStr )
{
    static int nAll = 0, nPro = 0;

    nAll++;
    if ( rStr.SearchAscii( "%PRODUCT" ) != STRING_NOTFOUND )
    {
        String &rProductName = ProductName::get();
        String &rVersion = Version::get();
        String &rAboutBoxVersion = AboutBoxVersion::get();
        String &rExtension = Extension::get();

        if ( !rProductName.Len() )
        {
            rtl::OUString aTmp;
            Any aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTNAME );
            aRet >>= aTmp;
            rProductName = aTmp;

            aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTVERSION );
            aRet >>= aTmp;
            rVersion = aTmp;

            aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::ABOUTBOXPRODUCTVERSION );
            aRet >>= aTmp;
            rAboutBoxVersion = aTmp;

            if ( !rExtension.Len() )
            {
                aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTEXTENSION );
                aRet >>= aTmp;
                rExtension = aTmp;
            }
        }

        nPro++;
        rStr.SearchAndReplaceAllAscii( "%PRODUCTNAME", rProductName );
        rStr.SearchAndReplaceAllAscii( "%PRODUCTVERSION", rVersion );
        rStr.SearchAndReplaceAllAscii( "%ABOUTBOXPRODUCTVERSION", rAboutBoxVersion );
        rStr.SearchAndReplaceAllAscii( "%PRODUCTEXTENSION", rExtension );
    }
}

//==============================================================================
class ServiceImpl
    : public ::cppu::WeakImplHelper2<ui::dialogs::XAsynchronousExecutableDialog,
                                     task::XJobExecutor>
{
    Reference<XComponentContext> const m_xComponentContext;
    boost::optional< Reference<awt::XWindow> > /* const */ m_parent;
    boost::optional<OUString> /* const */ m_view;
    boost::optional<Sequence<OUString> > m_extensions;
    OUString m_initialTitle;

public:
    ServiceImpl( Sequence<Any> const & args,
                 Reference<XComponentContext> const & xComponentContext );

    // XAsynchronousExecutableDialog
    virtual void SAL_CALL setDialogTitle( OUString const & aTitle )
        throw (RuntimeException);
    virtual void SAL_CALL startExecuteModal(
        Reference< ui::dialogs::XDialogClosedListener > const & xListener )
        throw (RuntimeException);

    // XJobExecutor
    virtual void SAL_CALL trigger( OUString const & event )
        throw (RuntimeException);
};

//______________________________________________________________________________
ServiceImpl::ServiceImpl( Sequence<Any> const& args,
                          Reference<XComponentContext> const& xComponentContext)
    : m_xComponentContext(xComponentContext)
{
    try {
        comphelper::unwrapArgs( args, m_parent, m_view );
        return;
    } catch (css::lang::IllegalArgumentException & ) {
    }
    try {
        comphelper::unwrapArgs( args, m_extensions, m_view );
    } catch (css::lang::IllegalArgumentException & ) {
    }

    ResHookProc pProc = ResMgr::GetReadStringHook();
    if ( !pProc )
        ResMgr::SetReadStringHook( ReplaceProductNameHookProc );
}

// XAsynchronousExecutableDialog
//______________________________________________________________________________
void ServiceImpl::setDialogTitle( OUString const & title )
    throw (RuntimeException)
{
    if (::dp_gui::DialogImpl::s_dialog.is()) {
        const ::vos::OGuard guard( Application::GetSolarMutex() );
        ::dp_gui::DialogImpl::get(
            m_xComponentContext,
            m_parent ? *m_parent : Reference<awt::XWindow>(),
            m_extensions ? *m_extensions : Sequence<OUString>(),
            m_view ? *m_view : OUString() )->SetText( title );
    }
    else
        m_initialTitle = title;
}

//______________________________________________________________________________
void ServiceImpl::startExecuteModal(
    Reference< ui::dialogs::XDialogClosedListener > const & xListener )
    throw (RuntimeException)
{
    ::std::auto_ptr<Application> app;
    if (! dp_gui::DialogImpl::s_dialog.is())
    {
        const bool bAppUp = (GetpApp() != 0);
        bool bOfficePipePresent;
        try {
            bOfficePipePresent = dp_misc::office_is_running();
        }
        catch (Exception & exc) {
            if (bAppUp) {
                const vos::OGuard guard( Application::GetSolarMutex() );
                std::auto_ptr<ErrorBox> box(
                    new ErrorBox( Application::GetActiveTopWindow(),
                                  WB_OK, exc.Message ) );
                box->Execute();
            }
            throw;
        }

        if (! bOfficePipePresent) {
            OSL_ASSERT( ! bAppUp );
            app.reset( new MyApp );
            if (! InitVCL( Reference<lang::XMultiServiceFactory>(
                               m_xComponentContext->getServiceManager(),
                               UNO_QUERY_THROW ) ))
                throw RuntimeException( OUSTR("Cannot initialize VCL!"),
                                        static_cast<OWeakObject *>(this) );
            AllSettings as = app->GetSettings();
            OUString slang;
            if (! (::utl::ConfigManager::GetDirectConfigProperty(
                       ::utl::ConfigManager::LOCALE ) >>= slang))
                throw RuntimeException( OUSTR("Cannot determine language!"),
                                        static_cast<OWeakObject *>(this) );
            as.SetUILanguage( MsLangId::convertIsoStringToLanguage( slang ) );
            app->SetSettings( as );
        }
    }
    else
    {
        //Currently we do not support the case that if the Extension Manager is
        //open in an office an unopkg can be executed. This should be fixed in the future.
        ResId warnId(WARNINGBOX_CONCURRENTINSTANCE,*DeploymentGuiResMgr::get() );
        WarningBox warn(NULL, warnId);
        warn.Execute();
    }

    {
        const ::vos::OGuard guard( Application::GetSolarMutex() );
        ::rtl::Reference< ::dp_gui::DialogImpl > dialog(
            ::dp_gui::DialogImpl::get(
                m_xComponentContext,
                m_parent ? *m_parent : Reference<awt::XWindow>(),
                m_extensions ? *m_extensions : Sequence<OUString>(),
                m_view ? *m_view : OUString() ) );
        if (m_initialTitle.getLength() > 0) {
            dialog->SetText( m_initialTitle );
            m_initialTitle = OUString();
        }
        dialog->Show();
        dialog->ToTop( TOTOP_RESTOREWHENMIN );
    }

    if (app.get() != 0) {
        Application::Execute();
        DeInitVCL();
    }

    if (xListener.is())
        xListener->dialogClosed(
            ui::dialogs::DialogClosedEvent(
                static_cast< ::cppu::OWeakObject * >(this),
                sal_Int16(0)) );
}

// XJobExecutor
//______________________________________________________________________________
void ServiceImpl::trigger( OUString const & ) throw (RuntimeException)
{
    startExecuteModal( Reference< ui::dialogs::XDialogClosedListener >() );
}

namespace sdecl = comphelper::service_decl;
sdecl::class_<ServiceImpl, sdecl::with_args<true> > serviceSI;
sdecl::ServiceDecl const serviceDecl(
    serviceSI,
    "com.sun.star.comp.deployment.ui.PackageManagerDialog",
    "com.sun.star.deployment.ui.PackageManagerDialog" );

sdecl::class_<LicenseDialog, sdecl::with_args<true> > licenseSI;
sdecl::ServiceDecl const licenseDecl(
    licenseSI,
    "com.sun.star.comp.deployment.ui.LicenseDialog",
    "com.sun.star.deployment.ui.LicenseDialog" );
} // namespace dp_gui

extern "C" {

void SAL_CALL component_getImplementationEnvironment(
    const sal_Char ** ppEnvTypeName, uno_Environment ** )
{
    *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
}

sal_Bool SAL_CALL component_writeInfo(
    lang::XMultiServiceFactory * pServiceManager,
    registry::XRegistryKey * pRegistryKey )
{
    return component_writeInfoHelper(
        pServiceManager, pRegistryKey, dp_gui::serviceDecl, dp_gui::licenseDecl );
}

void * SAL_CALL component_getFactory(
    sal_Char const * pImplName,
    lang::XMultiServiceFactory * pServiceManager,
    registry::XRegistryKey * pRegistryKey )
{
    return component_getFactoryHelper(
        pImplName, pServiceManager, pRegistryKey, dp_gui::serviceDecl, dp_gui::licenseDecl );
}

} // extern "C"
<commit_msg>INTEGRATION: CWS updchk10 (1.18.16); FILE MERGED 2007/10/16 06:24:33 dv 1.18.16.1: Added support for showin update dialog only<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: dp_gui_service.cxx,v $
 *
 *  $Revision: 1.19 $
 *
 *  last change: $Author: ihi $ $Date: 2007-11-19 16:52:27 $
 *
 *  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_desktop.hxx"

#include "dp_gui_shared.hxx"
#include "dp_gui.h"
#include "cppuhelper/implbase2.hxx"
#include "cppuhelper/implementationentry.hxx"
#include "unotools/configmgr.hxx"
#include "comphelper/servicedecl.hxx"
#include "comphelper/unwrapargs.hxx"
#include <i18npool/mslangid.hxx>
#include "vcl/svapp.hxx"
#include "vcl/msgbox.hxx"
#include "com/sun/star/lang/XServiceInfo.hpp"
#include "com/sun/star/task/XJobExecutor.hpp"
#include "com/sun/star/ui/dialogs/XAsynchronousExecutableDialog.hpp"

#include "boost/bind.hpp"
#include "license_dialog.hxx"

using namespace ::dp_misc;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;

using ::rtl::OUString;

namespace css = ::com::sun::star;
namespace dp_gui {

//==============================================================================
class MyApp : public Application, private boost::noncopyable
{
public:
    MyApp();
    virtual ~MyApp();

    // Application
    virtual void Main();
};

//______________________________________________________________________________
MyApp::~MyApp()
{
}

//______________________________________________________________________________
MyApp::MyApp()
{
}

//______________________________________________________________________________
void MyApp::Main()
{
}

//##############################################################################

namespace
{
    struct ProductName
        : public rtl::Static< String, ProductName > {};
    struct Version
        : public rtl::Static< String, Version > {};
    struct AboutBoxVersion
        : public rtl::Static< String, AboutBoxVersion > {};
    struct Extension
        : public rtl::Static< String, Extension > {};
}

void ReplaceProductNameHookProc( String& rStr )
{
    static int nAll = 0, nPro = 0;

    nAll++;
    if ( rStr.SearchAscii( "%PRODUCT" ) != STRING_NOTFOUND )
    {
        String &rProductName = ProductName::get();
        String &rVersion = Version::get();
        String &rAboutBoxVersion = AboutBoxVersion::get();
        String &rExtension = Extension::get();

        if ( !rProductName.Len() )
        {
            rtl::OUString aTmp;
            Any aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTNAME );
            aRet >>= aTmp;
            rProductName = aTmp;

            aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTVERSION );
            aRet >>= aTmp;
            rVersion = aTmp;

            aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::ABOUTBOXPRODUCTVERSION );
            aRet >>= aTmp;
            rAboutBoxVersion = aTmp;

            if ( !rExtension.Len() )
            {
                aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTEXTENSION );
                aRet >>= aTmp;
                rExtension = aTmp;
            }
        }

        nPro++;
        rStr.SearchAndReplaceAllAscii( "%PRODUCTNAME", rProductName );
        rStr.SearchAndReplaceAllAscii( "%PRODUCTVERSION", rVersion );
        rStr.SearchAndReplaceAllAscii( "%ABOUTBOXPRODUCTVERSION", rAboutBoxVersion );
        rStr.SearchAndReplaceAllAscii( "%PRODUCTEXTENSION", rExtension );
    }
}

//==============================================================================
class ServiceImpl
    : public ::cppu::WeakImplHelper2<ui::dialogs::XAsynchronousExecutableDialog,
                                     task::XJobExecutor>
{
    Reference<XComponentContext> const m_xComponentContext;
    boost::optional< Reference<awt::XWindow> > /* const */ m_parent;
    boost::optional<OUString> /* const */ m_view;
    boost::optional<Sequence<OUString> > m_extensions;
    OUString m_initialTitle;
    bool m_bShowUpdateOnly;

public:
    ServiceImpl( Sequence<Any> const & args,
                 Reference<XComponentContext> const & xComponentContext );

    // XAsynchronousExecutableDialog
    virtual void SAL_CALL setDialogTitle( OUString const & aTitle )
        throw (RuntimeException);
    virtual void SAL_CALL startExecuteModal(
        Reference< ui::dialogs::XDialogClosedListener > const & xListener )
        throw (RuntimeException);

    // XJobExecutor
    virtual void SAL_CALL trigger( OUString const & event )
        throw (RuntimeException);
};

//______________________________________________________________________________
ServiceImpl::ServiceImpl( Sequence<Any> const& args,
                          Reference<XComponentContext> const& xComponentContext)
    : m_xComponentContext(xComponentContext),
      m_bShowUpdateOnly( false )
{
    try {
        comphelper::unwrapArgs( args, m_parent, m_view );
        return;
    } catch (css::lang::IllegalArgumentException & ) {
    }
    try {
        comphelper::unwrapArgs( args, m_extensions, m_view );
    } catch (css::lang::IllegalArgumentException & ) {
    }

    ResHookProc pProc = ResMgr::GetReadStringHook();
    if ( !pProc )
        ResMgr::SetReadStringHook( ReplaceProductNameHookProc );
}

// XAsynchronousExecutableDialog
//______________________________________________________________________________
void ServiceImpl::setDialogTitle( OUString const & title )
    throw (RuntimeException)
{
    if (::dp_gui::DialogImpl::s_dialog.is()) {
        const ::vos::OGuard guard( Application::GetSolarMutex() );
        ::dp_gui::DialogImpl::get(
            m_xComponentContext,
            m_parent ? *m_parent : Reference<awt::XWindow>(),
            m_extensions ? *m_extensions : Sequence<OUString>(),
            m_view ? *m_view : OUString() )->SetText( title );
    }
    else
        m_initialTitle = title;
}

//______________________________________________________________________________
void ServiceImpl::startExecuteModal(
    Reference< ui::dialogs::XDialogClosedListener > const & xListener )
    throw (RuntimeException)
{
    bool bCloseDialog = true;  // only used if m_bShowUpdateOnly is true
    ::std::auto_ptr<Application> app;
    if (! dp_gui::DialogImpl::s_dialog.is())
    {
        const bool bAppUp = (GetpApp() != 0);
        bool bOfficePipePresent;
        try {
            bOfficePipePresent = dp_misc::office_is_running();
        }
        catch (Exception & exc) {
            if (bAppUp) {
                const vos::OGuard guard( Application::GetSolarMutex() );
                std::auto_ptr<ErrorBox> box(
                    new ErrorBox( Application::GetActiveTopWindow(),
                                  WB_OK, exc.Message ) );
                box->Execute();
            }
            throw;
        }

        if (! bOfficePipePresent) {
            OSL_ASSERT( ! bAppUp );
            app.reset( new MyApp );
            if (! InitVCL( Reference<lang::XMultiServiceFactory>(
                               m_xComponentContext->getServiceManager(),
                               UNO_QUERY_THROW ) ))
                throw RuntimeException( OUSTR("Cannot initialize VCL!"),
                                        static_cast<OWeakObject *>(this) );
            AllSettings as = app->GetSettings();
            OUString slang;
            if (! (::utl::ConfigManager::GetDirectConfigProperty(
                       ::utl::ConfigManager::LOCALE ) >>= slang))
                throw RuntimeException( OUSTR("Cannot determine language!"),
                                        static_cast<OWeakObject *>(this) );
            as.SetUILanguage( MsLangId::convertIsoStringToLanguage( slang ) );
            app->SetSettings( as );
        }
    }
    else
    {
        // When m_bShowUpdateOnly is set, we are inside the office and the user clicked
        // the update notification icon in the menu bar. We must not close the extensions
        // dialog after displaying the update dialog when it has been visible before
        if ( m_bShowUpdateOnly )
            bCloseDialog = false;
        else
        {
            //Currently we do not support the case that if the Extension Manager is
            //open in an office an unopkg can be executed. This should be fixed in the future.
            ResId warnId(WARNINGBOX_CONCURRENTINSTANCE,*DeploymentGuiResMgr::get() );
            WarningBox warn(NULL, warnId);
            warn.Execute();
        }
    }

    {
        const ::vos::OGuard guard( Application::GetSolarMutex() );
        ::rtl::Reference< ::dp_gui::DialogImpl > dialog(
            ::dp_gui::DialogImpl::get(
                m_xComponentContext,
                m_parent ? *m_parent : Reference<awt::XWindow>(),
                m_extensions ? *m_extensions : Sequence<OUString>(),
                m_view ? *m_view : OUString() ) );
        if (m_initialTitle.getLength() > 0) {
            dialog->SetText( m_initialTitle );
            m_initialTitle = OUString();
        }
        if ( m_bShowUpdateOnly )
        {
            dialog->checkUpdates( false, true, !bCloseDialog );
            if ( bCloseDialog )
                dialog->Close();
            else
                dialog->ToTop( TOTOP_RESTOREWHENMIN );
        }
        else
        {
            dialog->Show();
            dialog->ToTop( TOTOP_RESTOREWHENMIN );
        }
    }

    if (app.get() != 0) {
        Application::Execute();
        DeInitVCL();
    }

    if (xListener.is())
        xListener->dialogClosed(
            ui::dialogs::DialogClosedEvent(
                static_cast< ::cppu::OWeakObject * >(this),
                sal_Int16(0)) );
}

// XJobExecutor
//______________________________________________________________________________
void ServiceImpl::trigger( OUString const &rEvent ) throw (RuntimeException)
{
    if ( rEvent == OUSTR("SHOW_UPDATE_DIALOG") )
        m_bShowUpdateOnly = true;
    else
        m_bShowUpdateOnly = false;

    startExecuteModal( Reference< ui::dialogs::XDialogClosedListener >() );
}

namespace sdecl = comphelper::service_decl;
sdecl::class_<ServiceImpl, sdecl::with_args<true> > serviceSI;
sdecl::ServiceDecl const serviceDecl(
    serviceSI,
    "com.sun.star.comp.deployment.ui.PackageManagerDialog",
    "com.sun.star.deployment.ui.PackageManagerDialog" );

sdecl::class_<LicenseDialog, sdecl::with_args<true> > licenseSI;
sdecl::ServiceDecl const licenseDecl(
    licenseSI,
    "com.sun.star.comp.deployment.ui.LicenseDialog",
    "com.sun.star.deployment.ui.LicenseDialog" );
} // namespace dp_gui

extern "C" {

void SAL_CALL component_getImplementationEnvironment(
    const sal_Char ** ppEnvTypeName, uno_Environment ** )
{
    *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
}

sal_Bool SAL_CALL component_writeInfo(
    lang::XMultiServiceFactory * pServiceManager,
    registry::XRegistryKey * pRegistryKey )
{
    return component_writeInfoHelper(
        pServiceManager, pRegistryKey, dp_gui::serviceDecl, dp_gui::licenseDecl );
}

void * SAL_CALL component_getFactory(
    sal_Char const * pImplName,
    lang::XMultiServiceFactory * pServiceManager,
    registry::XRegistryKey * pRegistryKey )
{
    return component_getFactoryHelper(
        pImplName, pServiceManager, pRegistryKey, dp_gui::serviceDecl, dp_gui::licenseDecl );
}

} // extern "C"
<|endoftext|>


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

#include "kdepasteprotocol.h"

#include <utils/qtcassert.h>

#include <QDebug>
#include <QXmlStreamReader>
#include <QByteArray>
#include <QStringList>

#include <QNetworkReply>

#include <algorithm>

enum { debug = 0 };

static inline QByteArray expiryParameter(int daysRequested)
{
    // Obtained by 'pastebin.kde.org/api/xml/parameter/expire' on 11.11.2013
    static const int expiryTimesMin[] = {1800, 21600, 86400, 604800, 2592000};
    const int *end = expiryTimesMin + sizeof(expiryTimesMin) / sizeof(expiryTimesMin[0]);
    // Find the first element >= requested span, search up to n - 1 such that 'end' defaults to last value.
    const int *match = std::lower_bound(expiryTimesMin, end - 1, 24 * 60 * daysRequested);
    return QByteArray("expire=") + QByteArray::number(*match);
}

namespace CodePaster {
StickyNotesPasteProtocol::StickyNotesPasteProtocol() :
    m_fetchReply(0),
    m_pasteReply(0),
    m_listReply(0),
    m_fetchId(-1),
    m_postId(-1),
    m_hostChecked(false)
{
}

void StickyNotesPasteProtocol::setHostUrl(const QString &hostUrl)
{
    m_hostUrl = hostUrl;
    if (!m_hostUrl.endsWith(QLatin1Char('/')))
        m_hostUrl.append(QLatin1Char('/'));
}

unsigned StickyNotesPasteProtocol::capabilities() const
{
    return ListCapability | PostDescriptionCapability;
}

bool StickyNotesPasteProtocol::checkConfiguration(QString *errorMessage)
{
    if (m_hostChecked)  // Check the host once.
        return true;
    const bool ok = httpStatus(m_hostUrl, errorMessage);
    if (ok)
        m_hostChecked = true;
    return ok;
}

// Query 'http://pastebin.kde.org/api/xml/parameter/language' to obtain the valid values.
static inline QByteArray pasteLanguage(Protocol::ContentType ct)
{
    switch (ct) {
    case Protocol::Text:
        break;
    case Protocol::C:
        return "language=c";
    case Protocol::Cpp:
        return "language=cpp-qt";
    case Protocol::JavaScript:
        return "language=javascript";
    case Protocol::Diff:
        return "language=diff";
    case Protocol::Xml:
        return "language=xml";
    }
    return QByteArray("language=text");
}

void StickyNotesPasteProtocol::paste(const QString &text,
                                   ContentType ct, int expiryDays,
                                   const QString &username,
                                   const QString &comment,
                                   const QString &description)
{
    enum { maxDescriptionLength = 30 }; // Length of description is limited.

    Q_UNUSED(username)
    Q_UNUSED(comment);
    QTC_ASSERT(!m_pasteReply, return);

    // Format body
    QByteArray pasteData = "&data=";
    pasteData += QUrl::toPercentEncoding(fixNewLines(text));
    pasteData += '&';
    pasteData += pasteLanguage(ct);
    pasteData += '&';
    pasteData += expiryParameter(expiryDays);
    if (!description.isEmpty()) {
        pasteData += "&title=";
        pasteData += QUrl::toPercentEncoding(description.left(maxDescriptionLength));
    }

    m_pasteReply = httpPost(m_hostUrl + QLatin1String("api/xml/create"), pasteData);
    connect(m_pasteReply, SIGNAL(finished()), this, SLOT(pasteFinished()));
    if (debug)
        qDebug() << "paste: sending " << m_pasteReply << pasteData;
}

// Parse for an element and return its contents
static QString parseElement(QIODevice *device, const QString &elementName)
{
    QXmlStreamReader reader(device);
    while (!reader.atEnd()) {
        if (reader.readNext() == QXmlStreamReader::StartElement
            && reader.name() == elementName)
            return reader.readElementText();
    }
    return QString();
}

void StickyNotesPasteProtocol::pasteFinished()
{
    if (m_pasteReply->error()) {
        qWarning("%s protocol error: %s", qPrintable(name()),qPrintable(m_pasteReply->errorString()));
    } else {
        // Parse id from '<result><id>143204</id><hash></hash></result>'
        // No useful error reports have been observed.
        const QString id = parseElement(m_pasteReply, QLatin1String("id"));
        if (id.isEmpty())
            qWarning("%s protocol error: Could not send entry.", qPrintable(name()));
        else
            emit pasteDone(m_hostUrl + id);
    }

    m_pasteReply->deleteLater();
    m_pasteReply = 0;
}

void StickyNotesPasteProtocol::fetch(const QString &id)
{
    QTC_ASSERT(!m_fetchReply, return);

    // Did we get a complete URL or just an id?
    m_fetchId = id;
    const int lastSlashPos = m_fetchId.lastIndexOf(QLatin1Char('/'));
    if (lastSlashPos != -1)
        m_fetchId.remove(0, lastSlashPos + 1);
    QString url = m_hostUrl + QLatin1String("api/xml/show/") + m_fetchId;
    if (debug)
        qDebug() << "fetch: sending " << url;

    m_fetchReply = httpGet(url);
    connect(m_fetchReply, SIGNAL(finished()), this, SLOT(fetchFinished()));
}

// Parse: '<result><id>143228</id><author>foo</author><timestamp>1320661026</timestamp><language>text</language>
//  <data>bar</data></result>'

void StickyNotesPasteProtocol::fetchFinished()
{
    const QString title = name() + QLatin1String(": ") + m_fetchId;
    QString content;
    const bool error = m_fetchReply->error();
    if (error) {
        content = m_fetchReply->errorString();
        if (debug)
            qDebug() << "fetchFinished: error" << m_fetchId << content;
    } else {
        content = parseElement(m_fetchReply, QLatin1String("data"));
        content.remove(QLatin1Char('\r'));
    }
    m_fetchReply->deleteLater();
    m_fetchReply = 0;
    emit fetchDone(title, content, error);
}

void StickyNotesPasteProtocol::list()
{
    QTC_ASSERT(!m_listReply, return);

    // Trailing slash is important to prevent redirection.
    QString url = m_hostUrl + QLatin1String("api/xml/list");
    m_listReply = httpGet(url);
    connect(m_listReply, SIGNAL(finished()), this, SLOT(listFinished()));
    if (debug)
        qDebug() << "list: sending " << url << m_listReply;
}

// Parse 'result><pastes><paste>id1</paste><paste>id2</paste>...'
static inline QStringList parseList(QIODevice *device)
{
    QStringList result;
    QXmlStreamReader reader(device);
    const QString pasteElement = QLatin1String("paste");
    while (!reader.atEnd()) {
        if (reader.readNext() == QXmlStreamReader::StartElement && reader.name() == pasteElement)
            result.append(reader.readElementText());
    }
    return result;
}

void StickyNotesPasteProtocol::listFinished()
{
    const bool error = m_listReply->error();
    if (error) {
        if (debug)
            qDebug() << "listFinished: error" << m_listReply->errorString();
    } else {
        emit listDone(name(), parseList(m_listReply));
    }
    m_listReply->deleteLater();
    m_listReply = 0;
}

QString KdePasteProtocol::protocolName()
{
    return QLatin1String("Paste.KDE.Org");
}

} // namespace CodePaster
<commit_msg>CPaster: Fix expiry determination<commit_after>/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include "kdepasteprotocol.h"

#include <utils/qtcassert.h>

#include <QDebug>
#include <QXmlStreamReader>
#include <QByteArray>
#include <QStringList>

#include <QNetworkReply>

#include <algorithm>

enum { debug = 0 };

static inline QByteArray expiryParameter(int daysRequested)
{
    // Obtained by 'pastebin.kde.org/api/xml/parameter/expire' on 26.03.2014
    static const int expiryTimesSec[] = {1800, 21600, 86400, 604800, 2592000, 31536000};
    const int *end = expiryTimesSec + sizeof(expiryTimesSec) / sizeof(expiryTimesSec[0]);
    // Find the first element >= requested span, search up to n - 1 such that 'end' defaults to last value.
    const int *match = std::lower_bound(expiryTimesSec, end - 1, 24 * 60 * 60 * daysRequested);
    return QByteArray("expire=") + QByteArray::number(*match);
}

namespace CodePaster {
StickyNotesPasteProtocol::StickyNotesPasteProtocol() :
    m_fetchReply(0),
    m_pasteReply(0),
    m_listReply(0),
    m_fetchId(-1),
    m_postId(-1),
    m_hostChecked(false)
{
}

void StickyNotesPasteProtocol::setHostUrl(const QString &hostUrl)
{
    m_hostUrl = hostUrl;
    if (!m_hostUrl.endsWith(QLatin1Char('/')))
        m_hostUrl.append(QLatin1Char('/'));
}

unsigned StickyNotesPasteProtocol::capabilities() const
{
    return ListCapability | PostDescriptionCapability;
}

bool StickyNotesPasteProtocol::checkConfiguration(QString *errorMessage)
{
    if (m_hostChecked)  // Check the host once.
        return true;
    const bool ok = httpStatus(m_hostUrl, errorMessage);
    if (ok)
        m_hostChecked = true;
    return ok;
}

// Query 'http://pastebin.kde.org/api/xml/parameter/language' to obtain the valid values.
static inline QByteArray pasteLanguage(Protocol::ContentType ct)
{
    switch (ct) {
    case Protocol::Text:
        break;
    case Protocol::C:
        return "language=c";
    case Protocol::Cpp:
        return "language=cpp-qt";
    case Protocol::JavaScript:
        return "language=javascript";
    case Protocol::Diff:
        return "language=diff";
    case Protocol::Xml:
        return "language=xml";
    }
    return QByteArray("language=text");
}

void StickyNotesPasteProtocol::paste(const QString &text,
                                   ContentType ct, int expiryDays,
                                   const QString &username,
                                   const QString &comment,
                                   const QString &description)
{
    enum { maxDescriptionLength = 30 }; // Length of description is limited.

    Q_UNUSED(username)
    Q_UNUSED(comment);
    QTC_ASSERT(!m_pasteReply, return);

    // Format body
    QByteArray pasteData = "&data=";
    pasteData += QUrl::toPercentEncoding(fixNewLines(text));
    pasteData += '&';
    pasteData += pasteLanguage(ct);
    pasteData += '&';
    pasteData += expiryParameter(expiryDays);
    if (!description.isEmpty()) {
        pasteData += "&title=";
        pasteData += QUrl::toPercentEncoding(description.left(maxDescriptionLength));
    }

    m_pasteReply = httpPost(m_hostUrl + QLatin1String("api/xml/create"), pasteData);
    connect(m_pasteReply, SIGNAL(finished()), this, SLOT(pasteFinished()));
    if (debug)
        qDebug() << "paste: sending " << m_pasteReply << pasteData;
}

// Parse for an element and return its contents
static QString parseElement(QIODevice *device, const QString &elementName)
{
    QXmlStreamReader reader(device);
    while (!reader.atEnd()) {
        if (reader.readNext() == QXmlStreamReader::StartElement
            && reader.name() == elementName)
            return reader.readElementText();
    }
    return QString();
}

void StickyNotesPasteProtocol::pasteFinished()
{
    if (m_pasteReply->error()) {
        qWarning("%s protocol error: %s", qPrintable(name()),qPrintable(m_pasteReply->errorString()));
    } else {
        // Parse id from '<result><id>143204</id><hash></hash></result>'
        // No useful error reports have been observed.
        const QString id = parseElement(m_pasteReply, QLatin1String("id"));
        if (id.isEmpty())
            qWarning("%s protocol error: Could not send entry.", qPrintable(name()));
        else
            emit pasteDone(m_hostUrl + id);
    }

    m_pasteReply->deleteLater();
    m_pasteReply = 0;
}

void StickyNotesPasteProtocol::fetch(const QString &id)
{
    QTC_ASSERT(!m_fetchReply, return);

    // Did we get a complete URL or just an id?
    m_fetchId = id;
    const int lastSlashPos = m_fetchId.lastIndexOf(QLatin1Char('/'));
    if (lastSlashPos != -1)
        m_fetchId.remove(0, lastSlashPos + 1);
    QString url = m_hostUrl + QLatin1String("api/xml/show/") + m_fetchId;
    if (debug)
        qDebug() << "fetch: sending " << url;

    m_fetchReply = httpGet(url);
    connect(m_fetchReply, SIGNAL(finished()), this, SLOT(fetchFinished()));
}

// Parse: '<result><id>143228</id><author>foo</author><timestamp>1320661026</timestamp><language>text</language>
//  <data>bar</data></result>'

void StickyNotesPasteProtocol::fetchFinished()
{
    const QString title = name() + QLatin1String(": ") + m_fetchId;
    QString content;
    const bool error = m_fetchReply->error();
    if (error) {
        content = m_fetchReply->errorString();
        if (debug)
            qDebug() << "fetchFinished: error" << m_fetchId << content;
    } else {
        content = parseElement(m_fetchReply, QLatin1String("data"));
        content.remove(QLatin1Char('\r'));
    }
    m_fetchReply->deleteLater();
    m_fetchReply = 0;
    emit fetchDone(title, content, error);
}

void StickyNotesPasteProtocol::list()
{
    QTC_ASSERT(!m_listReply, return);

    // Trailing slash is important to prevent redirection.
    QString url = m_hostUrl + QLatin1String("api/xml/list");
    m_listReply = httpGet(url);
    connect(m_listReply, SIGNAL(finished()), this, SLOT(listFinished()));
    if (debug)
        qDebug() << "list: sending " << url << m_listReply;
}

// Parse 'result><pastes><paste>id1</paste><paste>id2</paste>...'
static inline QStringList parseList(QIODevice *device)
{
    QStringList result;
    QXmlStreamReader reader(device);
    const QString pasteElement = QLatin1String("paste");
    while (!reader.atEnd()) {
        if (reader.readNext() == QXmlStreamReader::StartElement && reader.name() == pasteElement)
            result.append(reader.readElementText());
    }
    return result;
}

void StickyNotesPasteProtocol::listFinished()
{
    const bool error = m_listReply->error();
    if (error) {
        if (debug)
            qDebug() << "listFinished: error" << m_listReply->errorString();
    } else {
        emit listDone(name(), parseList(m_listReply));
    }
    m_listReply->deleteLater();
    m_listReply = 0;
}

QString KdePasteProtocol::protocolName()
{
    return QLatin1String("Paste.KDE.Org");
}

} // namespace CodePaster
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include <ncurses.h>

#include "catch.hpp"

#include "../lib.hh"

using namespace vick;
using namespace vick::find;

TEST_CASE("move_forward_find") {
    contents contents({" hi man search way too hard for me"});

    move_forward_find(contents, 'o', 2);
    CHECK(contents.x == 21);
    move_forward_find(contents, 'm', 1);
    CHECK(contents.x == 32);
}

TEST_CASE("move_backward_find") {
    contents contents({" Simple text to search on"});
    contents.x = 24;

    move_backward_find(contents, 'e', 1);
    CHECK(contents.x == 17);
    move_backward_find(contents, ' ', 1);
    CHECK(contents.x == 15);
}

TEST_CASE("move_forward_until_match") {
    contents contents({" hi man search way too hard for me"});

    move_forward_until_match(contents, 'o', 2);
    CHECK(contents.x == 20);
    move_forward_until_match(contents, 'm', 1);
    CHECK(contents.x == 31);
}

TEST_CASE("move_backward_until_match") {
    contents contents({" Simple text to search on"});
    contents.x = 24;

    move_backward_until_match(contents, 'e', 1);
    CHECK(contents.x == 18);
    move_backward_until_match(contents, ' ', 1);
    CHECK(contents.x == 16);
}
<commit_msg>Use `size() - 1` instead of hard coding it<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include <ncurses.h>

#include "catch.hpp"

#include "../lib.hh"

using namespace vick;
using namespace vick::find;

TEST_CASE("move_forward_find") {
    contents contents({" hi man search way too hard for me"});

    move_forward_find(contents, 'o', 2);
    CHECK(contents.x == 21);
    move_forward_find(contents, 'm', 1);
    CHECK(contents.x == 32);
}

TEST_CASE("move_backward_find") {
    contents contents({" Simple text to search on"});
    contents.x = contents.cont[0].size() - 1;

    move_backward_find(contents, 'e', 1);
    CHECK(contents.x == 17);
    move_backward_find(contents, ' ', 1);
    CHECK(contents.x == 15);
}

TEST_CASE("move_forward_until_match") {
    contents contents({" hi man search way too hard for me"});

    move_forward_until_match(contents, 'o', 2);
    CHECK(contents.x == 20);
    move_forward_until_match(contents, 'm', 1);
    CHECK(contents.x == 31);
}

TEST_CASE("move_backward_until_match") {
    contents contents({" Simple text to search on"});
    contents.x = contents.cont[0].size() - 1;

    move_backward_until_match(contents, 'e', 1);
    CHECK(contents.x == 18);
    move_backward_until_match(contents, ' ', 1);
    CHECK(contents.x == 16);
}
<|endoftext|>


<commit_before>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/

#include "cppdeclfromdef.h"

#include <Literals.h> //### remove
#include <QDebug> //###remove

#include <AST.h>
#include <ASTVisitor.h>
#include <CoreTypes.h>
#include <Names.h>
#include <Symbols.h>
#include <TranslationUnit.h>
#include <cplusplus/ASTPath.h>
#include <cplusplus/InsertionPointLocator.h>
#include <cplusplus/LookupContext.h>
#include <cplusplus/Overview.h>

#include <QtCore/QCoreApplication>

using namespace CPlusPlus;
using namespace CppEditor;
using namespace CppEditor::Internal;
using namespace CppTools;

using CppEditor::CppRefactoringChanges;

namespace {

class Operation: public CppQuickFixOperation
{
public:
    Operation(const CppQuickFixState &state, int priority,
              const QString &targetFileName, const Class *targetSymbol,
              InsertionPointLocator::AccessSpec xsSpec,
              const QString &decl)
        : CppQuickFixOperation(state, priority)
        , m_targetFileName(targetFileName)
        , m_targetSymbol(targetSymbol)
        , m_xsSpec(xsSpec)
        , m_decl(decl)
    {
        QString type;
        switch (xsSpec) {
        case InsertionPointLocator::Public: type = QLatin1String("public"); break;
        case InsertionPointLocator::Protected: type = QLatin1String("protected"); break;
        case InsertionPointLocator::Private: type = QLatin1String("private"); break;
        case InsertionPointLocator::PublicSlot: type = QLatin1String("public slot"); break;
        case InsertionPointLocator::ProtectedSlot: type = QLatin1String("protected slot"); break;
        case InsertionPointLocator::PrivateSlot: type = QLatin1String("private slot"); break;
        default: break;
        }

        setDescription(QCoreApplication::tr("Create %1 Declaration from Definition",
                                            "CppEditor::DeclFromDef").arg(type));
    }

    void createChanges()
    {
        CppRefactoringChanges *changes = refactoringChanges();

        Document::Ptr targetDoc = changes->document(m_targetFileName);
        InsertionPointLocator locator(targetDoc);
        const InsertionLocation loc = locator.methodDeclarationInClass(m_targetSymbol, m_xsSpec);
        Q_ASSERT(loc.isValid());

        int targetPosition1 = changes->positionInFile(m_targetFileName, loc.line(), loc.column());
        int targetPosition2 = qMax(0, changes->positionInFile(m_targetFileName, loc.line(), 1) - 1);

        Utils::ChangeSet target;
        target.insert(targetPosition1, loc.prefix() + m_decl);
        changes->changeFile(m_targetFileName, target);

        changes->reindent(m_targetFileName,
                          Utils::ChangeSet::Range(targetPosition2, targetPosition1));

        changes->openEditor(m_targetFileName, loc.line(), loc.column());
    }

private:
    QString m_targetFileName;
    const Class *m_targetSymbol;
    InsertionPointLocator::AccessSpec m_xsSpec;
    QString m_decl;
};

} // anonymous namespace

QList<CppQuickFixOperation::Ptr> DeclFromDef::match(const CppQuickFixState &state)
{
    const QList<AST *> &path = state.path();

    FunctionDefinitionAST *funDef = 0;
    int idx = 0;
    for (; idx < path.size(); ++idx) {
        AST *node = path.at(idx);
        if (FunctionDefinitionAST *candidate = node->asFunctionDefinition()) {
            if (!funDef && state.isCursorOn(candidate) && !state.isCursorOn(candidate->function_body))
                funDef = candidate;
        } else if (node->asClassSpecifier()) {
            return noResult();
        }
    }

    if (!funDef || !funDef->symbol)
        return noResult();

    Function *method = funDef->symbol;

    if (ClassOrNamespace *targetBinding = state.context().lookupParent(method)) {
        foreach (Symbol *s, targetBinding->symbols()) {
            if (Class *clazz = s->asClass()) {
                QList<CppQuickFixOperation::Ptr> results;
                const QLatin1String fn(clazz->fileName());
                const QString decl = generateDeclaration(state,
                                                         method,
                                                         targetBinding);
                results.append(singleResult(new Operation(state, idx, fn, clazz,
                                                          InsertionPointLocator::Public,
                                                          decl)));
                results.append(singleResult(new Operation(state, idx, fn, clazz,
                                                          InsertionPointLocator::Protected,
                                                          decl)));
                results.append(singleResult(new Operation(state, idx, fn, clazz,
                                                          InsertionPointLocator::Private,
                                                          decl)));
                results.append(singleResult(new Operation(state, idx, fn, clazz,
                                                          InsertionPointLocator::PublicSlot,
                                                          decl)));
                results.append(singleResult(new Operation(state, idx, fn, clazz,
                                                          InsertionPointLocator::ProtectedSlot,
                                                          decl)));
                results.append(singleResult(new Operation(state, idx, fn, clazz,
                                                          InsertionPointLocator::PrivateSlot,
                                                          decl)));
                return results;
            } //! \todo support insertion into namespaces
        }
    }

    return noResult();
}

QString DeclFromDef::generateDeclaration(const CppQuickFixState &state,
                                         Function *method,
                                         ClassOrNamespace *targetBinding)
{
    Q_UNUSED(targetBinding);

    Overview oo;
    oo.setShowFunctionSignatures(true);
    oo.setShowReturnTypes(true);
    oo.setShowArgumentNames(true);

    QString decl;
    decl += oo(method->type(), method->identity());
    decl += QLatin1String(";\n");

    return decl;
}
<commit_msg>Removed unused formal argument.<commit_after>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/

#include "cppdeclfromdef.h"

#include <Literals.h> //### remove
#include <QDebug> //###remove

#include <AST.h>
#include <ASTVisitor.h>
#include <CoreTypes.h>
#include <Names.h>
#include <Symbols.h>
#include <TranslationUnit.h>
#include <cplusplus/ASTPath.h>
#include <cplusplus/InsertionPointLocator.h>
#include <cplusplus/LookupContext.h>
#include <cplusplus/Overview.h>

#include <QtCore/QCoreApplication>

using namespace CPlusPlus;
using namespace CppEditor;
using namespace CppEditor::Internal;
using namespace CppTools;

using CppEditor::CppRefactoringChanges;

namespace {

class Operation: public CppQuickFixOperation
{
public:
    Operation(const CppQuickFixState &state, int priority,
              const QString &targetFileName, const Class *targetSymbol,
              InsertionPointLocator::AccessSpec xsSpec,
              const QString &decl)
        : CppQuickFixOperation(state, priority)
        , m_targetFileName(targetFileName)
        , m_targetSymbol(targetSymbol)
        , m_xsSpec(xsSpec)
        , m_decl(decl)
    {
        QString type;
        switch (xsSpec) {
        case InsertionPointLocator::Public: type = QLatin1String("public"); break;
        case InsertionPointLocator::Protected: type = QLatin1String("protected"); break;
        case InsertionPointLocator::Private: type = QLatin1String("private"); break;
        case InsertionPointLocator::PublicSlot: type = QLatin1String("public slot"); break;
        case InsertionPointLocator::ProtectedSlot: type = QLatin1String("protected slot"); break;
        case InsertionPointLocator::PrivateSlot: type = QLatin1String("private slot"); break;
        default: break;
        }

        setDescription(QCoreApplication::tr("Create %1 Declaration from Definition",
                                            "CppEditor::DeclFromDef").arg(type));
    }

    void createChanges()
    {
        CppRefactoringChanges *changes = refactoringChanges();

        Document::Ptr targetDoc = changes->document(m_targetFileName);
        InsertionPointLocator locator(targetDoc);
        const InsertionLocation loc = locator.methodDeclarationInClass(m_targetSymbol, m_xsSpec);
        Q_ASSERT(loc.isValid());

        int targetPosition1 = changes->positionInFile(m_targetFileName, loc.line(), loc.column());
        int targetPosition2 = qMax(0, changes->positionInFile(m_targetFileName, loc.line(), 1) - 1);

        Utils::ChangeSet target;
        target.insert(targetPosition1, loc.prefix() + m_decl);
        changes->changeFile(m_targetFileName, target);

        changes->reindent(m_targetFileName,
                          Utils::ChangeSet::Range(targetPosition2, targetPosition1));

        changes->openEditor(m_targetFileName, loc.line(), loc.column());
    }

private:
    QString m_targetFileName;
    const Class *m_targetSymbol;
    InsertionPointLocator::AccessSpec m_xsSpec;
    QString m_decl;
};

} // anonymous namespace

QList<CppQuickFixOperation::Ptr> DeclFromDef::match(const CppQuickFixState &state)
{
    const QList<AST *> &path = state.path();

    FunctionDefinitionAST *funDef = 0;
    int idx = 0;
    for (; idx < path.size(); ++idx) {
        AST *node = path.at(idx);
        if (FunctionDefinitionAST *candidate = node->asFunctionDefinition()) {
            if (!funDef && state.isCursorOn(candidate) && !state.isCursorOn(candidate->function_body))
                funDef = candidate;
        } else if (node->asClassSpecifier()) {
            return noResult();
        }
    }

    if (!funDef || !funDef->symbol)
        return noResult();

    Function *method = funDef->symbol;

    if (ClassOrNamespace *targetBinding = state.context().lookupParent(method)) {
        foreach (Symbol *s, targetBinding->symbols()) {
            if (Class *clazz = s->asClass()) {
                QList<CppQuickFixOperation::Ptr> results;
                const QLatin1String fn(clazz->fileName());
                const QString decl = generateDeclaration(state,
                                                         method,
                                                         targetBinding);
                results.append(singleResult(new Operation(state, idx, fn, clazz,
                                                          InsertionPointLocator::Public,
                                                          decl)));
                results.append(singleResult(new Operation(state, idx, fn, clazz,
                                                          InsertionPointLocator::Protected,
                                                          decl)));
                results.append(singleResult(new Operation(state, idx, fn, clazz,
                                                          InsertionPointLocator::Private,
                                                          decl)));
                results.append(singleResult(new Operation(state, idx, fn, clazz,
                                                          InsertionPointLocator::PublicSlot,
                                                          decl)));
                results.append(singleResult(new Operation(state, idx, fn, clazz,
                                                          InsertionPointLocator::ProtectedSlot,
                                                          decl)));
                results.append(singleResult(new Operation(state, idx, fn, clazz,
                                                          InsertionPointLocator::PrivateSlot,
                                                          decl)));
                return results;
            } //! \todo support insertion into namespaces
        }
    }

    return noResult();
}

QString DeclFromDef::generateDeclaration(const CppQuickFixState &,
                                         Function *method,
                                         ClassOrNamespace *targetBinding)
{
    Q_UNUSED(targetBinding);

    Overview oo;
    oo.setShowFunctionSignatures(true);
    oo.setShowReturnTypes(true);
    oo.setShowArgumentNames(true);

    QString decl;
    decl += oo(method->type(), method->identity());
    decl += QLatin1String(";\n");

    return decl;
}
<|endoftext|>


<commit_before>// Debugging Settings
//#define DEBUG
//#define DEBUG_V1
//#define DEBUG_V2
//#define DEBUG_V3
//#define DEBUG_V4

#include <iostream>
#include <iomanip>
#include <memory>
#include <random>
#include <iterator>
#include <functional>
#include <ctime>

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <memory.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/resource.h>
#include <math.h>

#include <bsl_memory.h>
#include <bslma_testallocator.h>
#include <bslma_newdeleteallocator.h>
#include <bsls_stopwatch.h>

#include <bdlma_sequentialpool.h>
#include <bdlma_sequentialallocator.h>
#include <bdlma_bufferedsequentialallocator.h>
#include <bdlma_multipoolallocator.h>

#include <vector>
#include <list>

#include "benchmark_common.h"

// Debugging
#include <typeinfo>
#include <assert.h>

using namespace BloombergLP;

// Global Variables

#ifdef DEBUG
int AF_RF_PRODUCT = 256;
#else
int AF_RF_PRODUCT = 2560;
#endif // DEBUG

template<typename ALLOC>
class AllocSubsystem {
public:
	ALLOC d_alloc;
	std::list<int, alloc_adaptor<int, ALLOC> > d_list;
	AllocSubsystem() : d_alloc(), d_list(&d_alloc) {}
};

class DefaultSubsystem {
public:
	std::list<int> d_list;
	DefaultSubsystem() : d_list() {}
};

// Convenience typedefs
struct subsystems {
	typedef DefaultSubsystem def;
	typedef AllocSubsystem<BloombergLP::bdlma::MultipoolAllocator> multipool;
};

template<typename VECTOR>
double access_lists(VECTOR *vec, int af, int rf) {
#ifdef DEBUG_V3
	std::cout << "Accessing Lists" << std::endl;
#endif // DEBUG_V3

	std::clock_t c_start = std::clock();

	for (size_t r = 0; r < rf; r++)	{
		for (size_t i = 0; i < vec->size(); i++) {
			for (size_t a = 0; a < af; a++) {
				for (auto it = (*vec)[i]->d_list.begin(); it != (*vec)[i]->d_list.end(); ++it) {
					(*it)++; // Increment int to cause loop to have some effect
				}
				clobber(); // TODO will this hurt caching?
			}
		}
	}
	std::clock_t c_end = std::clock();

#ifdef DEBUG_V3
	std::cout << "Finished accessing Lists" << std::endl;
#endif // DEBUG_V3
	return (c_end - c_start) * 1.0 / CLOCKS_PER_SEC;
}

template<typename SUBSYS>
double run_combination(int G, int S, int af, int sf, int rf) {
	// G  = Total system size (# subsystems * elements in subsystems). Given as power of 2 (size really = 2^G)
	// S  = Elements per subsystem. Given as power of 2 (size really = 2^S)
	// af = Access Factor - Number of iterations through a subsystem (linked list) before moving to the next
	// sf = Shuffle Factor - Number of elements popped from each list and pushed to a randomly chosen list
	//						 Note: -ve value means access occurs before shuffle
	// rf = Repeat Factor - Number of times the subsystems are iterated over

	int k = std::abs(G) - std::abs(S);
	size_t expanded_S = 1, expanded_k = 1;
	expanded_S <<= S;
	expanded_k <<= k;

#ifdef DEBUG_V3
	std::cout << "Total number of lists (k) = 2^" << k << " (aka " << expanded_k << ")" << std::endl;
	std::cout << "Total number of elements per sub system (S) = 2^" << S << " (aka " << expanded_S << ")" << std::endl;
#endif // DEBUG_V3

	std::vector<SUBSYS *> vec;

	// Create data under test
	vec.reserve(expanded_k);
	for (size_t i = 0; i < expanded_k; i++)	{
		vec.emplace_back(new SUBSYS()); // Never deallocated because we exit immediately after this function reutrns anyway

		for (size_t j = 0; j < expanded_S; j++)
		{
			vec.back()->d_list.emplace_back((int)j);
		}
	}

#ifdef DEBUG_V3
	std::cout << "Created vector with " << vec.size() << " elements" << std::endl;
#endif // DEBUG_V3

	double result = 0.0;
	if (sf < 0) {
		// Access the data
#ifdef DEBUG_V3
		std::cout << "Accessing data BEFORE shuffling" << std::endl;
#endif // DEBUG_V3
		result = access_lists(&vec, af, rf);
	}

	// Shuffle the data
#ifdef DEBUG_V3
	std::cout << "Shuffling data " << std::abs(sf) << " times" << std::endl;
#endif // DEBUG_V3

	std::default_random_engine generator(1); // Consistent seed to get the same (pseudo) random distribution each time
	std::uniform_int_distribution<size_t> position_distribution(0, vec.size() - 1);
	for (size_t i = 0; i < std::abs(sf); i++) {
		for (size_t j = 0; j < vec.size(); j++)	{

#ifdef DEBUG_V4
			std::cout << "Generating position" << std::endl;
#endif // DEBUG_V4
			size_t pos = position_distribution(generator);

			if (vec[j]->d_list.size() > 0) { // TODO: not quite what is in the paper
#ifdef DEBUG_V4
				std::cout << "Grabbing front element of list at " << j << std::endl;
#endif // DEBUG_V4
				int popped = vec[j]->d_list.front();

#ifdef DEBUG_V4
				std::cout << "Emplacing " << popped << " into list at " << pos << std::endl;
#endif // DEBUG_V4
				vec[pos]->d_list.emplace_back(popped);

#ifdef DEBUG_V4
				std::cout << "Popping from front of list at " << j << " with " << vec[j]->d_list.size() << " elements" << std::endl;
#endif // DEBUG_V4
				vec[j]->d_list.pop_front();
			}

#ifdef DEBUG_V4
			std::cout << "Finished iteration" << std::endl;
#endif // DEBUG_V4
		}
	}

	if (sf > 0) {
		// Access the data
#ifdef DEBUG_V3
		std::cout << "Accessing data AFTER shuffling" << std::endl;
#endif // DEBUG_V3
		result = access_lists(&vec, af, rf);
	}

#ifdef DEBUG_V3
	std::cout << "Done running combination" << std::endl;
#endif // DEBUG_V3

	return result;
}

void generate_table(int G, int alloc_num) {
	int sf = 5;
	for (int S = 21; S >= 0; S--) { // S = 21
		std::cout << "S=" << S << " " << std::flush;
		for (int af = 256; af >= 1; af >>= 1) {
			int rf = AF_RF_PRODUCT / af;
#ifdef DEBUG_V3
			std::cout << "G: " << G << " S: " << S << " af: " << af << " sf: " << sf << " rf: " << rf << std::endl;
#endif
			int pid = fork();
			if (pid == 0) { // Child process
				double result = 0;
				switch (alloc_num) {
					case 0: {
						result = run_combination<typename subsystems::def>(G, S, af, sf, rf);
						break;
					}

					case 7: {
						result = run_combination<typename subsystems::multipool>(G, S, af, sf, rf);
						break;
					}
				}
				std::cout << result << " " << std::flush;
				exit(0);
			}
			else {
				int error;
				wait(&error);
				if (error) {
					std::cout << "Error code " << error << "at G: " << G << " S: " << S << " af: " << af << " sf: " << sf << " rf: " << rf << std::endl;
				}
			}
		}
		std::cout << std::endl;
	}
}

int main(int argc, char *argv[]) {
	// TODO: Notes:
	// 1) Incremented int by 1 on each iteration of af, to prevent compiler optimizing away loop (also used Chandler's
	//    optimizer-defeating functions to access the ints after each iteration -- could this be a problem with caching?)
	// 2) Couldn't follow paper exactly, because popping off subsystems iteratively (then pushing randmonly) means that on
	//    2nd (and further) iterations through the list, some subsystems will not have an element to pop.

	// For baseline, G = 10^7, af = 10

	std::cout << "Started" << std::endl;

	std::cout << "Problem Size 2^21 Without Allocators" << std::endl;
	generate_table(21, 0);

	std::cout << "Problem Size 2^25 Without Allocators" << std::endl;
	generate_table(25, 0);

	std::cout << "Problem Size 2^21 With Allocators" << std::endl;
	generate_table(21, 7);

	std::cout << "Problem Size 2^25 With Allocators" << std::endl;
	generate_table(25, 7);

	std::cout << "Done" << std::endl;
}
<commit_msg>Rearranged test order<commit_after>// Debugging Settings
//#define DEBUG
//#define DEBUG_V1
//#define DEBUG_V2
//#define DEBUG_V3
//#define DEBUG_V4

#include <iostream>
#include <iomanip>
#include <memory>
#include <random>
#include <iterator>
#include <functional>
#include <ctime>

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <memory.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/resource.h>
#include <math.h>

#include <bsl_memory.h>
#include <bslma_testallocator.h>
#include <bslma_newdeleteallocator.h>
#include <bsls_stopwatch.h>

#include <bdlma_sequentialpool.h>
#include <bdlma_sequentialallocator.h>
#include <bdlma_bufferedsequentialallocator.h>
#include <bdlma_multipoolallocator.h>

#include <vector>
#include <list>

#include "benchmark_common.h"

// Debugging
#include <typeinfo>
#include <assert.h>

using namespace BloombergLP;

// Global Variables

#ifdef DEBUG
int AF_RF_PRODUCT = 256;
#else
int AF_RF_PRODUCT = 2560;
#endif // DEBUG

template<typename ALLOC>
class AllocSubsystem {
public:
	ALLOC d_alloc;
	std::list<int, alloc_adaptor<int, ALLOC> > d_list;
	AllocSubsystem() : d_alloc(), d_list(&d_alloc) {}
};

class DefaultSubsystem {
public:
	std::list<int> d_list;
	DefaultSubsystem() : d_list() {}
};

// Convenience typedefs
struct subsystems {
	typedef DefaultSubsystem def;
	typedef AllocSubsystem<BloombergLP::bdlma::MultipoolAllocator> multipool;
};

template<typename VECTOR>
double access_lists(VECTOR *vec, int af, int rf) {
#ifdef DEBUG_V3
	std::cout << "Accessing Lists" << std::endl;
#endif // DEBUG_V3

	std::clock_t c_start = std::clock();

	for (size_t r = 0; r < rf; r++)	{
		for (size_t i = 0; i < vec->size(); i++) {
			for (size_t a = 0; a < af; a++) {
				for (auto it = (*vec)[i]->d_list.begin(); it != (*vec)[i]->d_list.end(); ++it) {
					(*it)++; // Increment int to cause loop to have some effect
				}
				clobber(); // TODO will this hurt caching?
			}
		}
	}
	std::clock_t c_end = std::clock();

#ifdef DEBUG_V3
	std::cout << "Finished accessing Lists" << std::endl;
#endif // DEBUG_V3
	return (c_end - c_start) * 1.0 / CLOCKS_PER_SEC;
}

template<typename SUBSYS>
double run_combination(int G, int S, int af, int sf, int rf) {
	// G  = Total system size (# subsystems * elements in subsystems). Given as power of 2 (size really = 2^G)
	// S  = Elements per subsystem. Given as power of 2 (size really = 2^S)
	// af = Access Factor - Number of iterations through a subsystem (linked list) before moving to the next
	// sf = Shuffle Factor - Number of elements popped from each list and pushed to a randomly chosen list
	//						 Note: -ve value means access occurs before shuffle
	// rf = Repeat Factor - Number of times the subsystems are iterated over

	int k = std::abs(G) - std::abs(S);
	size_t expanded_S = 1, expanded_k = 1;
	expanded_S <<= S;
	expanded_k <<= k;

#ifdef DEBUG_V3
	std::cout << "Total number of lists (k) = 2^" << k << " (aka " << expanded_k << ")" << std::endl;
	std::cout << "Total number of elements per sub system (S) = 2^" << S << " (aka " << expanded_S << ")" << std::endl;
#endif // DEBUG_V3

	std::vector<SUBSYS *> vec;

	// Create data under test
	vec.reserve(expanded_k);
	for (size_t i = 0; i < expanded_k; i++)	{
		vec.emplace_back(new SUBSYS()); // Never deallocated because we exit immediately after this function reutrns anyway

		for (size_t j = 0; j < expanded_S; j++)
		{
			vec.back()->d_list.emplace_back((int)j);
		}
	}

#ifdef DEBUG_V3
	std::cout << "Created vector with " << vec.size() << " elements" << std::endl;
#endif // DEBUG_V3

	double result = 0.0;
	if (sf < 0) {
		// Access the data
#ifdef DEBUG_V3
		std::cout << "Accessing data BEFORE shuffling" << std::endl;
#endif // DEBUG_V3
		result = access_lists(&vec, af, rf);
	}

	// Shuffle the data
#ifdef DEBUG_V3
	std::cout << "Shuffling data " << std::abs(sf) << " times" << std::endl;
#endif // DEBUG_V3

	std::default_random_engine generator(1); // Consistent seed to get the same (pseudo) random distribution each time
	std::uniform_int_distribution<size_t> position_distribution(0, vec.size() - 1);
	for (size_t i = 0; i < std::abs(sf); i++) {
		for (size_t j = 0; j < vec.size(); j++)	{

#ifdef DEBUG_V4
			std::cout << "Generating position" << std::endl;
#endif // DEBUG_V4
			size_t pos = position_distribution(generator);

			if (vec[j]->d_list.size() > 0) { // TODO: not quite what is in the paper
#ifdef DEBUG_V4
				std::cout << "Grabbing front element of list at " << j << std::endl;
#endif // DEBUG_V4
				int popped = vec[j]->d_list.front();

#ifdef DEBUG_V4
				std::cout << "Emplacing " << popped << " into list at " << pos << std::endl;
#endif // DEBUG_V4
				vec[pos]->d_list.emplace_back(popped);

#ifdef DEBUG_V4
				std::cout << "Popping from front of list at " << j << " with " << vec[j]->d_list.size() << " elements" << std::endl;
#endif // DEBUG_V4
				vec[j]->d_list.pop_front();
			}

#ifdef DEBUG_V4
			std::cout << "Finished iteration" << std::endl;
#endif // DEBUG_V4
		}
	}

	if (sf > 0) {
		// Access the data
#ifdef DEBUG_V3
		std::cout << "Accessing data AFTER shuffling" << std::endl;
#endif // DEBUG_V3
		result = access_lists(&vec, af, rf);
	}

#ifdef DEBUG_V3
	std::cout << "Done running combination" << std::endl;
#endif // DEBUG_V3

	return result;
}

void generate_table(int G, int alloc_num) {
	int sf = 5;
	for (int S = 21; S >= 0; S--) { // S = 21
		std::cout << "S=" << S << " " << std::flush;
		for (int af = 256; af >= 1; af >>= 1) {
			int rf = AF_RF_PRODUCT / af;
#ifdef DEBUG_V3
			std::cout << "G: " << G << " S: " << S << " af: " << af << " sf: " << sf << " rf: " << rf << std::endl;
#endif
			int pid = fork();
			if (pid == 0) { // Child process
				double result = 0;
				switch (alloc_num) {
					case 0: {
						result = run_combination<typename subsystems::def>(G, S, af, sf, rf);
						break;
					}

					case 7: {
						result = run_combination<typename subsystems::multipool>(G, S, af, sf, rf);
						break;
					}
				}
				std::cout << result << " " << std::flush;
				exit(0);
			}
			else {
				int error;
				wait(&error);
				if (error) {
					std::cout << "Error code " << error << "at G: " << G << " S: " << S << " af: " << af << " sf: " << sf << " rf: " << rf << std::endl;
				}
			}
		}
		std::cout << std::endl;
	}
}

int main(int argc, char *argv[]) {
	// TODO: Notes:
	// 1) Incremented int by 1 on each iteration of af, to prevent compiler optimizing away loop (also used Chandler's
	//    optimizer-defeating functions to access the ints after each iteration -- could this be a problem with caching?)
	// 2) Couldn't follow paper exactly, because popping off subsystems iteratively (then pushing randmonly) means that on
	//    2nd (and further) iterations through the list, some subsystems will not have an element to pop.

	// For baseline, G = 10^7, af = 10

	std::cout << "Started" << std::endl;

	std::cout << "Problem Size 2^21 Without Allocators" << std::endl;
	generate_table(21, 0);

	std::cout << "Problem Size 2^21 With Allocators" << std::endl;
	generate_table(21, 7);

	std::cout << "Problem Size 2^25 Without Allocators" << std::endl;
	generate_table(25, 0);

	std::cout << "Problem Size 2^25 With Allocators" << std::endl;
	generate_table(25, 7);

	std::cout << "Done" << std::endl;
}
<|endoftext|>