<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: Legend.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 01:02:29 $
 *
 *  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
 *
 ************************************************************************/
#ifndef CHART_LEGEND_HXX
#define CHART_LEGEND_HXX

#include "ServiceMacros.hxx"

#ifndef CHART_OPROPERTYSET_HXX
#include "OPropertySet.hxx"
#endif
#ifndef CHART_MUTEXCONTAINER_HXX
#include "MutexContainer.hxx"
#endif
#ifndef _CPPUHELPER_IMPLBASE3_HXX_
#include <cppuhelper/implbase3.hxx>
#endif
#ifndef _COMPHELPER_UNO3_HXX_
#include <comphelper/uno3.hxx>
#endif

#ifndef _COM_SUN_STAR_CHART2_XLEGEND_HPP_
#include <com/sun/star/chart2/XLegend.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif
#ifndef _COM_SUN_STAR_CHART2_XIDENTIFIABLE_HPP_
#include <com/sun/star/chart2/XIdentifiable.hpp>
#endif
#ifndef _COM_SUN_STAR_UNO_XCOMPONENTCONTEXT_HPP_
#include <com/sun/star/uno/XComponentContext.hpp>
#endif

namespace chart
{

namespace impl
{
typedef ::cppu::WeakImplHelper3<
    ::com::sun::star::chart2::XLegend,
    ::com::sun::star::lang::XServiceInfo,
    ::com::sun::star::chart2::XIdentifiable >
    Legend_Base;
}

class Legend :
    public helper::MutexContainer,
    public impl::Legend_Base,
    public ::property::OPropertySet
{
public:
    Legend( ::com::sun::star::uno::Reference<
            ::com::sun::star::uno::XComponentContext > const & xContext );
    virtual ~Legend();

    /// establish methods for factory instatiation
    APPHELPER_SERVICE_FACTORY_HELPER( Legend )

    /// XServiceInfo declarations
    APPHELPER_XSERVICEINFO_DECL()

    /// merge XInterface implementations
     DECLARE_XINTERFACE()
    /// merge XTypeProvider implementations
     DECLARE_XTYPEPROVIDER()

protected:
    // ____ OPropertySet ____
    virtual ::com::sun::star::uno::Any GetDefaultValue( sal_Int32 nHandle ) const
        throw(::com::sun::star::beans::UnknownPropertyException);

    // ____ OPropertySet ____
    virtual ::cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper();

    // ____ XPropertySet ____
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL
        getPropertySetInfo()
        throw (::com::sun::star::uno::RuntimeException);

//  virtual sal_Bool SAL_CALL convertFastPropertyValue
//         ( ::com::sun::star::uno::Any & rConvertedValue,
//           ::com::sun::star::uno::Any & rOldValue,
//           sal_Int32 nHandle,
//           const ::com::sun::star::uno::Any& rValue )
//      throw (::com::sun::star::lang::IllegalArgumentException);

    // ____ XLegend ____
    virtual void SAL_CALL registerEntry( const ::com::sun::star::uno::Reference<
                                         ::com::sun::star::chart2::XLegendEntry >& xEntry )
        throw (::com::sun::star::lang::IllegalArgumentException,
               ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL revokeEntry( const ::com::sun::star::uno::Reference<
                                       ::com::sun::star::chart2::XLegendEntry >& xEntry )
        throw (::com::sun::star::container::NoSuchElementException,
               ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Sequence<
        ::com::sun::star::uno::Reference<
        ::com::sun::star::chart2::XLegendEntry > > SAL_CALL getEntries()
        throw (::com::sun::star::uno::RuntimeException);

    // ____ XIdentifiable ____
    virtual ::rtl::OUString SAL_CALL getIdentifier()
        throw (::com::sun::star::uno::RuntimeException);

private:
    typedef ::std::vector<
        ::com::sun::star::uno::Reference<
            ::com::sun::star::chart2::XLegendEntry > > tLegendEntries;

    tLegendEntries                                    m_aLegendEntries;
    ::rtl::OUString                                   m_aIdentifier;
};

} //  namespace chart

// CHART_LEGEND_HXX
#endif
<commit_msg>INTEGRATION: CWS chart2mst3 (1.4.4); FILE MERGED 2005/12/21 21:29:21 iha 1.4.4.6: remove identifiers from model objects and create an index based CID protocol instead for selection purposes 2005/11/03 11:59:18 bm 1.4.4.5: fire modify events on property change 2005/10/14 16:58:44 bm 1.4.4.4: model listener mechanism 2005/10/07 11:56:37 bm 1.4.4.3: RESYNC: (1.4-1.5); FILE MERGED 2005/03/30 16:31:09 bm 1.4.4.2: make model cloneable (+first undo implementation) 2004/02/13 16:51:34 bm 1.4.4.1: join from changes on branch bm_post_chart01<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: Legend.hxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: vg $ $Date: 2007-05-22 18:39:39 $
 *
 *  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
 *
 ************************************************************************/
#ifndef CHART_LEGEND_HXX
#define CHART_LEGEND_HXX

#include "ServiceMacros.hxx"
#include "ModifyListenerHelper.hxx"

#ifndef CHART_OPROPERTYSET_HXX
#include "OPropertySet.hxx"
#endif
#ifndef CHART_MUTEXCONTAINER_HXX
#include "MutexContainer.hxx"
#endif
#ifndef _CPPUHELPER_IMPLBASE5_HXX_
#include <cppuhelper/implbase5.hxx>
#endif
#ifndef _COMPHELPER_UNO3_HXX_
#include <comphelper/uno3.hxx>
#endif

#ifndef _COM_SUN_STAR_CHART2_XLEGEND_HPP_
#include <com/sun/star/chart2/XLegend.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif
#ifndef _COM_SUN_STAR_UNO_XCOMPONENTCONTEXT_HPP_
#include <com/sun/star/uno/XComponentContext.hpp>
#endif
#ifndef _COM_SUN_STAR_UTIL_XCLONEABLE_HPP_
#include <com/sun/star/util/XCloneable.hpp>
#endif
#ifndef _COM_SUN_STAR_UTIL_XMODIFYBROADCASTER_HPP_
#include <com/sun/star/util/XModifyBroadcaster.hpp>
#endif
#ifndef _COM_SUN_STAR_UTIL_XMODIFYLISTENER_HPP_
#include <com/sun/star/util/XModifyListener.hpp>
#endif

namespace chart
{

namespace impl
{
typedef ::cppu::WeakImplHelper5<
        ::com::sun::star::chart2::XLegend,
        ::com::sun::star::lang::XServiceInfo,
        ::com::sun::star::util::XCloneable,
        ::com::sun::star::util::XModifyBroadcaster,
        ::com::sun::star::util::XModifyListener >
    Legend_Base;
}

class Legend :
    public MutexContainer,
    public impl::Legend_Base,
    public ::property::OPropertySet
{
public:
    Legend( ::com::sun::star::uno::Reference<
            ::com::sun::star::uno::XComponentContext > const & xContext );
    virtual ~Legend();

    /// establish methods for factory instatiation
    APPHELPER_SERVICE_FACTORY_HELPER( Legend )

    /// XServiceInfo declarations
    APPHELPER_XSERVICEINFO_DECL()

    /// merge XInterface implementations
     DECLARE_XINTERFACE()
    /// merge XTypeProvider implementations
     DECLARE_XTYPEPROVIDER()

protected:
    explicit Legend( const Legend & rOther );

    // ____ OPropertySet ____
    virtual ::com::sun::star::uno::Any GetDefaultValue( sal_Int32 nHandle ) const
        throw(::com::sun::star::beans::UnknownPropertyException);

    // ____ OPropertySet ____
    virtual ::cppu::IPropertyArrayHelper & SAL_CALL getInfoHelper();

    // ____ XPropertySet ____
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL
        getPropertySetInfo()
        throw (::com::sun::star::uno::RuntimeException);

//  virtual sal_Bool SAL_CALL convertFastPropertyValue
//         ( ::com::sun::star::uno::Any & rConvertedValue,
//           ::com::sun::star::uno::Any & rOldValue,
//           sal_Int32 nHandle,
//           const ::com::sun::star::uno::Any& rValue )
//      throw (::com::sun::star::lang::IllegalArgumentException);

    // ____ XLegend ____
    virtual void SAL_CALL registerEntry( const ::com::sun::star::uno::Reference<
                                         ::com::sun::star::chart2::XLegendEntry >& xEntry )
        throw (::com::sun::star::lang::IllegalArgumentException,
               ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL revokeEntry( const ::com::sun::star::uno::Reference<
                                       ::com::sun::star::chart2::XLegendEntry >& xEntry )
        throw (::com::sun::star::container::NoSuchElementException,
               ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Sequence<
        ::com::sun::star::uno::Reference<
        ::com::sun::star::chart2::XLegendEntry > > SAL_CALL getEntries()
        throw (::com::sun::star::uno::RuntimeException);

    // ____ XCloneable ____
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::util::XCloneable > SAL_CALL createClone()
        throw (::com::sun::star::uno::RuntimeException);

    // ____ XModifyBroadcaster ____
    virtual void SAL_CALL addModifyListener(
        const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& aListener )
        throw (::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL removeModifyListener(
        const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& aListener )
        throw (::com::sun::star::uno::RuntimeException);

    // ____ XModifyListener ____
    virtual void SAL_CALL modified(
        const ::com::sun::star::lang::EventObject& aEvent )
        throw (::com::sun::star::uno::RuntimeException);

    // ____ XEventListener (base of XModifyListener) ____
    virtual void SAL_CALL disposing(
        const ::com::sun::star::lang::EventObject& Source )
        throw (::com::sun::star::uno::RuntimeException);

    // ____ OPropertySet ____
    virtual void firePropertyChangeEvent();

    void fireModifyEvent();

private:
    typedef ::std::vector<
        ::com::sun::star::uno::Reference<
            ::com::sun::star::chart2::XLegendEntry > > tLegendEntries;

    tLegendEntries                                    m_aLegendEntries;
    ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener > m_xModifyEventForwarder;
};

} //  namespace chart

// CHART_LEGEND_HXX
#endif
<|endoftext|>


<commit_before>#ifndef __PROTOCOL_API_HPP__
#define __PROTOCOL_API_HPP__

#include "errors.hpp"
#include <boost/serialization/vector.hpp>
#include <boost/serialization/utility.hpp>   /* for `std::pair` serialization */
#include <functional>
#include <utility>
#include <vector>

#include "concurrency/fifo_checker.hpp"
#include "concurrency/signal.hpp"
#include "timestamps.hpp"

/* This file describes the relationship between the protocol-specific logic for
each protocol and the protocol-agnostic logic that routes queries for all the
protocols. Each protocol defines a `protocol_t` struct that acts as a
"container" to hold all the types for that protocol. The protocol-agnostic logic
will be templatized on a `protocol_t`. `protocol_t` itself is never
instantiated. For a description of what `protocol_t` must be like, see
`rethinkdb/docs_internal/protocol_api_notes.hpp`. */

/* `namespace_interface_t` is the interface that the protocol-agnostic database
logic for query routing exposes to the protocol-specific query parser. */

template<class protocol_t>
struct namespace_interface_t {
    virtual typename protocol_t::read_response_t read(typename protocol_t::read_t, order_token_t tok, signal_t *interruptor) = 0;
    virtual typename protocol_t::write_response_t write(typename protocol_t::write_t, order_token_t tok, signal_t *interruptor) = 0;

protected:
    virtual ~namespace_interface_t() { }
};

/* Exceptions thrown by functions operating on `protocol_t::region_t` */

struct bad_region_exc_t : public std::exception {
    const char *what() const throw () {
        return "The set you're trying to compute cannot be expressed as a "
            "`region_t`.";
    }
};

struct bad_join_exc_t : public std::exception {
    const char *what() const throw () {
        return "You need to give a non-overlapping set of regions.";
    }
};

/* Some `protocol_t::region_t` functions can be implemented in terms of other
functions. Here are default implementations for those functions. */

template<class region_t>
bool region_is_empty(const region_t &r) {
    return region_is_superset(region_t::empty(), r);
}

template<class region_t>
bool region_overlaps(const region_t &r1, const region_t &r2) {
    return !region_is_empty(region_intersection(r1, r2));
}

/* Regions contained in region_map_t must never intersect. */
template<class protocol_t, class value_t>
class region_map_t {
public:
    typedef typename std::vector<std::pair<typename protocol_t::region_t, value_t> >::const_iterator const_iterator;

    region_map_t() THROWS_NOTHING { }
    region_map_t(typename protocol_t::region_t r, value_t v) THROWS_NOTHING {
        regions_and_values.push_back(std::make_pair(r, v));
    }

    explicit region_map_t(const std::vector<std::pair<typename protocol_t::region_t, value_t> > &x) THROWS_NOTHING :
        regions_and_values(x)
    {
        /* Make sure that the vector we were given is valid */
        DEBUG_ONLY(get_domain());
    }

    typename protocol_t::region_t get_domain() const THROWS_NOTHING {
        std::vector<typename protocol_t::region_t> regions;
        for (int i = 0; i < (int)regions_and_values.size(); i++) {
            regions.push_back(regions_and_values[i].first);
        }
        return region_join(regions);
    }

    std::vector<std::pair<typename protocol_t::region_t, value_t> > get_as_pairs() const {
        return regions_and_values;
    }

    const_iterator begin() const {
        return regions_and_values.begin();
    }

    const_iterator end() const {
        return regions_and_values.end();
    }

    region_map_t mask(typename protocol_t::region_t region) const {
        std::vector<std::pair<typename protocol_t::region_t, value_t> > masked_pairs;
        for (int i = 0; i < (int)regions_and_values.size(); i++) {
            typename protocol_t::region_t ixn = region_intersection(regions_and_values[i].first, region);
            if (!region_is_empty(ixn)) {
                masked_pairs.push_back(std::make_pair(ixn, regions_and_values[i].second));
            }
        }
        return region_map_t(masked_pairs);
    }

    // Important: 'update' assumes that new_values regions do not intersect
    region_map_t update(const region_map_t& new_values) {
        std::vector<typename protocol_t::region_t> overlay_regions;
        for (const_iterator i = new_values.begin(); i != new_values.end(); ++i) {
            overlay_regions.push_back((*i).first);
        }

        std::vector<std::pair<typename protocol_t::region_t, value_t> > updated_pairs;
        for (const_iterator i = begin(); i != end(); ++i) {
            typename protocol_t::region_t old = (*i).first;
            std::vector<typename protocol_t::region_t> old_subregions = region_subtract_many(old, overlay_regions);

            // Insert the unchanged parts of the old region into updated_pairs with the old value
            for (typename std::vector<typename protocol_t::region_t>::const_iterator j = old_subregions.begin(); j != old_subregions.end(); ++j) {
                updated_pairs.push_back(std::make_pair(*j, (*i).second));
            }
        }
        std::copy(new_values.begin(), new_values.end(), std::back_inserter(updated_pairs));

        return region_map_t(updated_pairs);
    }

private:
    std::vector<std::pair<typename protocol_t::region_t, value_t> > regions_and_values;
    RDB_MAKE_ME_SERIALIZABLE_1(regions_and_values);
};

template<class protocol_t, class old_t, class new_t, class callable_t>
region_map_t<protocol_t, new_t> region_map_transform(const region_map_t<protocol_t, old_t> &original, const callable_t &callable) {
    std::vector<std::pair<typename protocol_t::region_t, old_t> > original_pairs = original.get_as_pairs();
    std::vector<std::pair<typename protocol_t::region_t, new_t> > new_pairs;
    for (int i = 0; i < (int)original_pairs.size(); i++) {
        new_pairs.push_back(std::make_pair(
                original_pairs[i].first,
                callable(original_pairs[i].second)
                ));
    }
    return region_map_t<protocol_t, new_t>(new_pairs);
}

/* `store_view_t` is an abstract class that represents a region of a key-value
store for some protocol. It's templatized on the protocol (`protocol_t`). It
covers some `protocol_t::region_t`, which is returned by `get_region()`.

In addition to the actual data, `store_view_t` is responsible for keeping track
of metadata which is keyed by region. The metadata is currently implemented as
opaque binary blob (`binary_blob_t`).

Here are the possible call sequences for read/write transactions:
 - begin_read_transaction get_metainfo* [read|send_backfill] destructor
 - begin_write_transaction (get_metainfo|set_metainfo)* [read|write|send_backfill|recv_backfill] destructor
*/

template<class protocol_t>
class store_view_t {
public:
    virtual ~store_view_t() { }

    typename protocol_t::region_t get_region() {
        return region;
    }

    struct read_transaction_t {
        virtual ~read_transaction_t() { }

        /* Gets the metadata.
        [Precondition] `this` holds the superblock
        [Postcondition] return_value.get_domain() == view->get_region()
        [May block] */
        virtual region_map_t<protocol_t, binary_blob_t> get_metadata(
                signal_t *interruptor)
                THROWS_ONLY(interrupted_exc_t) = 0;

        /* Performs a read.
        [Precondition] `this` holds the superblock
        [Postcondition] `this` does not hold the superblock
        [May block] */
        virtual typename protocol_t::read_response_t read(
                const typename protocol_t::read_t &,
                signal_t *interruptor)
                THROWS_ONLY(interrupted_exc_t) = 0;

        /* Expresses the changes that have happened since `start_point` as a
        series of `backfill_chunk_t` objects.
        [Precondition] start_point.get_domain() <= view->get_region()
        [Precondition] `this` holds the superblock
        [Postcondition] `this` does not hold the superblock
        [May block] */
        virtual void send_backfill(
                const region_map_t<protocol_t, state_timestamp_t> &start_point,
                const boost::function<void(typename protocol_t::backfill_chunk_t)> &chunk_fun,
                signal_t *interruptor)
                THROWS_ONLY(interrupted_exc_t) = 0;
    };

    /* Begins a read transaction. If there are any outstanding write
    transactions that still hold the superblock, blocks until they release the
    superblock.
    [May block] */
    virtual boost::shared_ptr<read_transaction_t> begin_read_transaction(
            signal_t *interruptor)
            THROWS_ONLY(interrupted_exc_t) = 0;

    struct write_transaction_t : public read_transaction_t {
        virtual ~write_transaction_t() { }

        /* Replaces the metadata over the view's entire range with the given
        metadata.
        [Precondition] `this` holds the superblock
        [Precondition] new_metadata.get_domain() == view->get_region()
        [Postcondition] this->get_metadata() == new_metadata
        [May block] */
        virtual void set_metadata(
                const region_map_t<protocol_t, binary_blob_t> &new_metadata)
                THROWS_NOTHING = 0;

        /* Performs a write.
        [Precondition] `this` holds the superblock
        [Precondition] region_is_superset(view->get_region(), write.get_region())
        [Postcondition] `this` does not hold the superblock
        [May block] */
        virtual typename protocol_t::write_response_t write(
                const typename protocol_t::write_t &write,
                transition_timestamp_t timestamp)
                THROWS_NOTHING = 0;

        /* Applies a backfill data chunk sent by `send_backfill()`. If
        `interrupted_exc_t` is thrown, the state of the database is undefined
        except that doing a second backfill must put it into a valid state.
        [Precondition] `this` holds the superblock
        [Postcondition] `this` does not hold the superblock
        [May block] */
        virtual void receive_backfill(
                const typename protocol_t::backfill_chunk_t &chunk,
                signal_t *interruptor)
                THROWS_ONLY(interrupted_exc_t) = 0;
    };

    /* Begins a write transaction. If there are any outstanding read or write
    transactions that still hold the superblock, blocks until they release the
    superblock.
    [May block] */
    virtual boost::shared_ptr<write_transaction_t> begin_write_transaction(
            signal_t *interruptor)
            THROWS_ONLY(interrupted_exc_t) = 0;

protected:
    explicit store_view_t(typename protocol_t::region_t r) : region(r) { }

private:
    typename protocol_t::region_t region;
};

/* The query-routing logic provides the following ordering guarantees:

1.  All the replicas of each individual key will see writes in the same order.

    Example: Suppose K = "x". You send (append "a" to K) and (append "b" to K)
    concurrently from different nodes. Either every copy of K will become "xab",
    or every copy of K will become "xba", but the different copies of K will
    never disagree.

2.  Queries from the same origin will be performed in same order they are sent.

    Example: Suppose K = "a". You send (set K to "b") and (read K) from the same
    thread on the same node, in that order. The read will return "b".

3.  Arbitrary atomic single-key operations can be performed, as long as they can
    be expressed as `protocol_t::write_t` objects.

4.  There are no other atomicity or ordering guarantees.

    Example: Suppose K1 = "x" and K2 = "x". You send (append "a" to every key)
    and (append "b" to every key) concurrently. Every copy of K1 will agree with
    every other copy of K1, and every copy of K2 will agree with every other
    copy of K2, but K1 and K2 may disagree.

    Example: Suppose K = "a". You send (set K to "b"). As soon as it's sent, you
    send (set K to "c") from a different node. K may end up being either "b" or
    "c".

    Example: Suppose K1 = "a" and K2 = "a". You send (set K1 to "b") and (set K2
    to "b") from the same node, in that order. Then you send (read K1 and K2)
    from a different node. The read may return (K1 = "a", K2 = "b").

5.  There is no simple way to perform an atomic multikey transaction. You might
    be able to fake it by using a key as a "lock".
*/

#endif /* __PROTOCOL_API_HPP__ */
<commit_msg>Add forgotten include<commit_after>#ifndef __PROTOCOL_API_HPP__
#define __PROTOCOL_API_HPP__

#include "errors.hpp"
#include <boost/serialization/vector.hpp>
#include <boost/serialization/utility.hpp>   /* for `std::pair` serialization */
#include <functional>
#include <utility>
#include <vector>

#include "concurrency/fifo_checker.hpp"
#include "concurrency/signal.hpp"
#include "rpc/serialize_macros.hpp"
#include "timestamps.hpp"

/* This file describes the relationship between the protocol-specific logic for
each protocol and the protocol-agnostic logic that routes queries for all the
protocols. Each protocol defines a `protocol_t` struct that acts as a
"container" to hold all the types for that protocol. The protocol-agnostic logic
will be templatized on a `protocol_t`. `protocol_t` itself is never
instantiated. For a description of what `protocol_t` must be like, see
`rethinkdb/docs_internal/protocol_api_notes.hpp`. */

/* `namespace_interface_t` is the interface that the protocol-agnostic database
logic for query routing exposes to the protocol-specific query parser. */

template<class protocol_t>
struct namespace_interface_t {
    virtual typename protocol_t::read_response_t read(typename protocol_t::read_t, order_token_t tok, signal_t *interruptor) = 0;
    virtual typename protocol_t::write_response_t write(typename protocol_t::write_t, order_token_t tok, signal_t *interruptor) = 0;

protected:
    virtual ~namespace_interface_t() { }
};

/* Exceptions thrown by functions operating on `protocol_t::region_t` */

struct bad_region_exc_t : public std::exception {
    const char *what() const throw () {
        return "The set you're trying to compute cannot be expressed as a "
            "`region_t`.";
    }
};

struct bad_join_exc_t : public std::exception {
    const char *what() const throw () {
        return "You need to give a non-overlapping set of regions.";
    }
};

/* Some `protocol_t::region_t` functions can be implemented in terms of other
functions. Here are default implementations for those functions. */

template<class region_t>
bool region_is_empty(const region_t &r) {
    return region_is_superset(region_t::empty(), r);
}

template<class region_t>
bool region_overlaps(const region_t &r1, const region_t &r2) {
    return !region_is_empty(region_intersection(r1, r2));
}

/* Regions contained in region_map_t must never intersect. */
template<class protocol_t, class value_t>
class region_map_t {
public:
    typedef typename std::vector<std::pair<typename protocol_t::region_t, value_t> >::const_iterator const_iterator;

    region_map_t() THROWS_NOTHING { }
    region_map_t(typename protocol_t::region_t r, value_t v) THROWS_NOTHING {
        regions_and_values.push_back(std::make_pair(r, v));
    }

    explicit region_map_t(const std::vector<std::pair<typename protocol_t::region_t, value_t> > &x) THROWS_NOTHING :
        regions_and_values(x)
    {
        /* Make sure that the vector we were given is valid */
        DEBUG_ONLY(get_domain());
    }

    typename protocol_t::region_t get_domain() const THROWS_NOTHING {
        std::vector<typename protocol_t::region_t> regions;
        for (int i = 0; i < (int)regions_and_values.size(); i++) {
            regions.push_back(regions_and_values[i].first);
        }
        return region_join(regions);
    }

    std::vector<std::pair<typename protocol_t::region_t, value_t> > get_as_pairs() const {
        return regions_and_values;
    }

    const_iterator begin() const {
        return regions_and_values.begin();
    }

    const_iterator end() const {
        return regions_and_values.end();
    }

    region_map_t mask(typename protocol_t::region_t region) const {
        std::vector<std::pair<typename protocol_t::region_t, value_t> > masked_pairs;
        for (int i = 0; i < (int)regions_and_values.size(); i++) {
            typename protocol_t::region_t ixn = region_intersection(regions_and_values[i].first, region);
            if (!region_is_empty(ixn)) {
                masked_pairs.push_back(std::make_pair(ixn, regions_and_values[i].second));
            }
        }
        return region_map_t(masked_pairs);
    }

    // Important: 'update' assumes that new_values regions do not intersect
    region_map_t update(const region_map_t& new_values) {
        std::vector<typename protocol_t::region_t> overlay_regions;
        for (const_iterator i = new_values.begin(); i != new_values.end(); ++i) {
            overlay_regions.push_back((*i).first);
        }

        std::vector<std::pair<typename protocol_t::region_t, value_t> > updated_pairs;
        for (const_iterator i = begin(); i != end(); ++i) {
            typename protocol_t::region_t old = (*i).first;
            std::vector<typename protocol_t::region_t> old_subregions = region_subtract_many(old, overlay_regions);

            // Insert the unchanged parts of the old region into updated_pairs with the old value
            for (typename std::vector<typename protocol_t::region_t>::const_iterator j = old_subregions.begin(); j != old_subregions.end(); ++j) {
                updated_pairs.push_back(std::make_pair(*j, (*i).second));
            }
        }
        std::copy(new_values.begin(), new_values.end(), std::back_inserter(updated_pairs));

        return region_map_t(updated_pairs);
    }

private:
    std::vector<std::pair<typename protocol_t::region_t, value_t> > regions_and_values;
    RDB_MAKE_ME_SERIALIZABLE_1(regions_and_values);
};

template<class protocol_t, class old_t, class new_t, class callable_t>
region_map_t<protocol_t, new_t> region_map_transform(const region_map_t<protocol_t, old_t> &original, const callable_t &callable) {
    std::vector<std::pair<typename protocol_t::region_t, old_t> > original_pairs = original.get_as_pairs();
    std::vector<std::pair<typename protocol_t::region_t, new_t> > new_pairs;
    for (int i = 0; i < (int)original_pairs.size(); i++) {
        new_pairs.push_back(std::make_pair(
                original_pairs[i].first,
                callable(original_pairs[i].second)
                ));
    }
    return region_map_t<protocol_t, new_t>(new_pairs);
}

/* `store_view_t` is an abstract class that represents a region of a key-value
store for some protocol. It's templatized on the protocol (`protocol_t`). It
covers some `protocol_t::region_t`, which is returned by `get_region()`.

In addition to the actual data, `store_view_t` is responsible for keeping track
of metadata which is keyed by region. The metadata is currently implemented as
opaque binary blob (`binary_blob_t`).

Here are the possible call sequences for read/write transactions:
 - begin_read_transaction get_metainfo* [read|send_backfill] destructor
 - begin_write_transaction (get_metainfo|set_metainfo)* [read|write|send_backfill|recv_backfill] destructor
*/

template<class protocol_t>
class store_view_t {
public:
    virtual ~store_view_t() { }

    typename protocol_t::region_t get_region() {
        return region;
    }

    struct read_transaction_t {
        virtual ~read_transaction_t() { }

        /* Gets the metadata.
        [Precondition] `this` holds the superblock
        [Postcondition] return_value.get_domain() == view->get_region()
        [May block] */
        virtual region_map_t<protocol_t, binary_blob_t> get_metadata(
                signal_t *interruptor)
                THROWS_ONLY(interrupted_exc_t) = 0;

        /* Performs a read.
        [Precondition] `this` holds the superblock
        [Postcondition] `this` does not hold the superblock
        [May block] */
        virtual typename protocol_t::read_response_t read(
                const typename protocol_t::read_t &,
                signal_t *interruptor)
                THROWS_ONLY(interrupted_exc_t) = 0;

        /* Expresses the changes that have happened since `start_point` as a
        series of `backfill_chunk_t` objects.
        [Precondition] start_point.get_domain() <= view->get_region()
        [Precondition] `this` holds the superblock
        [Postcondition] `this` does not hold the superblock
        [May block] */
        virtual void send_backfill(
                const region_map_t<protocol_t, state_timestamp_t> &start_point,
                const boost::function<void(typename protocol_t::backfill_chunk_t)> &chunk_fun,
                signal_t *interruptor)
                THROWS_ONLY(interrupted_exc_t) = 0;
    };

    /* Begins a read transaction. If there are any outstanding write
    transactions that still hold the superblock, blocks until they release the
    superblock.
    [May block] */
    virtual boost::shared_ptr<read_transaction_t> begin_read_transaction(
            signal_t *interruptor)
            THROWS_ONLY(interrupted_exc_t) = 0;

    struct write_transaction_t : public read_transaction_t {
        virtual ~write_transaction_t() { }

        /* Replaces the metadata over the view's entire range with the given
        metadata.
        [Precondition] `this` holds the superblock
        [Precondition] new_metadata.get_domain() == view->get_region()
        [Postcondition] this->get_metadata() == new_metadata
        [May block] */
        virtual void set_metadata(
                const region_map_t<protocol_t, binary_blob_t> &new_metadata)
                THROWS_NOTHING = 0;

        /* Performs a write.
        [Precondition] `this` holds the superblock
        [Precondition] region_is_superset(view->get_region(), write.get_region())
        [Postcondition] `this` does not hold the superblock
        [May block] */
        virtual typename protocol_t::write_response_t write(
                const typename protocol_t::write_t &write,
                transition_timestamp_t timestamp)
                THROWS_NOTHING = 0;

        /* Applies a backfill data chunk sent by `send_backfill()`. If
        `interrupted_exc_t` is thrown, the state of the database is undefined
        except that doing a second backfill must put it into a valid state.
        [Precondition] `this` holds the superblock
        [Postcondition] `this` does not hold the superblock
        [May block] */
        virtual void receive_backfill(
                const typename protocol_t::backfill_chunk_t &chunk,
                signal_t *interruptor)
                THROWS_ONLY(interrupted_exc_t) = 0;
    };

    /* Begins a write transaction. If there are any outstanding read or write
    transactions that still hold the superblock, blocks until they release the
    superblock.
    [May block] */
    virtual boost::shared_ptr<write_transaction_t> begin_write_transaction(
            signal_t *interruptor)
            THROWS_ONLY(interrupted_exc_t) = 0;

protected:
    explicit store_view_t(typename protocol_t::region_t r) : region(r) { }

private:
    typename protocol_t::region_t region;
};

/* The query-routing logic provides the following ordering guarantees:

1.  All the replicas of each individual key will see writes in the same order.

    Example: Suppose K = "x". You send (append "a" to K) and (append "b" to K)
    concurrently from different nodes. Either every copy of K will become "xab",
    or every copy of K will become "xba", but the different copies of K will
    never disagree.

2.  Queries from the same origin will be performed in same order they are sent.

    Example: Suppose K = "a". You send (set K to "b") and (read K) from the same
    thread on the same node, in that order. The read will return "b".

3.  Arbitrary atomic single-key operations can be performed, as long as they can
    be expressed as `protocol_t::write_t` objects.

4.  There are no other atomicity or ordering guarantees.

    Example: Suppose K1 = "x" and K2 = "x". You send (append "a" to every key)
    and (append "b" to every key) concurrently. Every copy of K1 will agree with
    every other copy of K1, and every copy of K2 will agree with every other
    copy of K2, but K1 and K2 may disagree.

    Example: Suppose K = "a". You send (set K to "b"). As soon as it's sent, you
    send (set K to "c") from a different node. K may end up being either "b" or
    "c".

    Example: Suppose K1 = "a" and K2 = "a". You send (set K1 to "b") and (set K2
    to "b") from the same node, in that order. Then you send (read K1 and K2)
    from a different node. The read may return (K1 = "a", K2 = "b").

5.  There is no simple way to perform an atomic multikey transaction. You might
    be able to fake it by using a key as a "lock".
*/

#endif /* __PROTOCOL_API_HPP__ */
<|endoftext|>


<commit_before>/*
  +----------------------------------------------------------------------+
  | PHP Version 5                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 1997-2013 The PHP Group                                |
  +----------------------------------------------------------------------+
  | http://www.opensource.org/licenses/mit-license.php  MIT License      |
  +----------------------------------------------------------------------+
  | Author: Jani Taskinen <jani.taskinen@iki.fi>                         |
  | Author: Patrick Reilly <preilly@php.net>                             |
  +----------------------------------------------------------------------+
*/

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "php_v8js_macros.h"

extern "C" {
#include "php_ini.h"
#include "ext/standard/info.h"
#include "ext/standard/php_string.h"
#include "ext/standard/php_smart_str.h"
}

#include "v8js_class.h"
#include "v8js_exceptions.h"
#include "v8js_v8object_class.h"

ZEND_DECLARE_MODULE_GLOBALS(v8js)

/* {{{ INI Settings */

static ZEND_INI_MH(v8js_OnUpdateV8Flags) /* {{{ */
{
	if (new_value) {
		if (V8JSG(v8_flags)) {
			free(V8JSG(v8_flags));
			V8JSG(v8_flags) = NULL;
		}
		if (!new_value[0]) {
			return FAILURE;
		}
		V8JSG(v8_flags) = zend_strndup(new_value, new_value_length);
	}

	return SUCCESS;
}

static ZEND_INI_MH(v8js_OnUpdateUseDate) /* {{{ */
{
	bool value;
	if (new_value_length==2 && strcasecmp("on", new_value)==0) {
		value = (bool) 1;
    } else if (new_value_length==3 && strcasecmp("yes", new_value)==0) {
		value = (bool) 1;
	} else if (new_value_length==4 && strcasecmp("true", new_value)==0) {
		value = (bool) 1;
	} else {
		value = (bool) atoi(new_value);
	}
	V8JSG(use_date) = value;
	return SUCCESS;
}
/* }}} */

static ZEND_INI_MH(v8js_OnUpdateUseArrayAccess) /* {{{ */
{
	bool value;
	if (new_value_length==2 && strcasecmp("on", new_value)==0) {
		value = (bool) 1;
    } else if (new_value_length==3 && strcasecmp("yes", new_value)==0) {
		value = (bool) 1;
	} else if (new_value_length==4 && strcasecmp("true", new_value)==0) {
		value = (bool) 1;
	} else {
		value = (bool) atoi(new_value);
	}
	V8JSG(use_array_access) = value;
	return SUCCESS;
}
/* }}} */

static ZEND_INI_MH(v8js_OnUpdateCompatExceptions) /* {{{ */
{
	bool value;
	if (new_value_length==2 && strcasecmp("on", new_value)==0) {
		value = (bool) 1;
    } else if (new_value_length==3 && strcasecmp("yes", new_value)==0) {
		value = (bool) 1;
	} else if (new_value_length==4 && strcasecmp("true", new_value)==0) {
		value = (bool) 1;
	} else {
		value = (bool) atoi(new_value);
	}
	V8JSG(compat_php_exceptions) = value;
	return SUCCESS;
}
/* }}} */

ZEND_INI_BEGIN() /* {{{ */
	ZEND_INI_ENTRY("v8js.flags", NULL, ZEND_INI_ALL, v8js_OnUpdateV8Flags)
	ZEND_INI_ENTRY("v8js.use_date", "0", ZEND_INI_ALL, v8js_OnUpdateUseDate)
	ZEND_INI_ENTRY("v8js.use_array_access", "0", ZEND_INI_ALL, v8js_OnUpdateUseArrayAccess)
	ZEND_INI_ENTRY("v8js.compat_php_exceptions", "0", ZEND_INI_ALL, v8js_OnUpdateCompatExceptions)
ZEND_INI_END()
/* }}} */

/* }}} INI */

#ifdef COMPILE_DL_V8JS
ZEND_GET_MODULE(v8js)
#endif

/* {{{ PHP_MINIT_FUNCTION
 */
PHP_MINIT_FUNCTION(v8js)
{
	PHP_MINIT(v8js_class)(INIT_FUNC_ARGS_PASSTHRU);
	PHP_MINIT(v8js_exceptions)(INIT_FUNC_ARGS_PASSTHRU);
	PHP_MINIT(v8js_v8object_class)(INIT_FUNC_ARGS_PASSTHRU);

	REGISTER_INI_ENTRIES();

	return SUCCESS;
}
/* }}} */

/* {{{ PHP_MSHUTDOWN_FUNCTION
 */
static PHP_MSHUTDOWN_FUNCTION(v8js)
{
	UNREGISTER_INI_ENTRIES();
	return SUCCESS;
}
/* }}} */

/* {{{ PHP_RSHUTDOWN_FUNCTION
 */
static PHP_RSHUTDOWN_FUNCTION(v8js)
{
	// If the timer thread is running then stop it
	if (V8JSG(timer_thread)) {
		V8JSG(timer_stop) = true;
		V8JSG(timer_thread)->join();
		V8JSG(timer_stop) = false;
		delete V8JSG(timer_thread);
		V8JSG(timer_thread) = NULL;
	}

	return SUCCESS;
}
/* }}} */

/* {{{ PHP_MINFO_FUNCTION
 */
static PHP_MINFO_FUNCTION(v8js)
{
	php_info_print_table_start();
	php_info_print_table_header(2, "V8 Javascript Engine", "enabled");
	php_info_print_table_header(2, "V8 Engine Compiled Version", PHP_V8_VERSION);
	php_info_print_table_header(2, "V8 Engine Linked Version", v8::V8::GetVersion());
	php_info_print_table_header(2, "Version", PHP_V8JS_VERSION);
	php_info_print_table_end();

	DISPLAY_INI_ENTRIES();
}
/* }}} */

/* {{{ PHP_GINIT_FUNCTION
 */
static PHP_GINIT_FUNCTION(v8js)
{
	/*
	  If ZTS is disabled, the v8js_globals instance is declared right
	  in the BSS and hence automatically initialized by C++ compiler.
	  Most of the variables are just zeroed.

	  If ZTS is enabled however, v8js_globals just points to a freshly
	  allocated, uninitialized piece of memory, hence we need to
	  initialize all fields on our own.  Likewise on shutdown we have to
	  run the destructors manually.
	*/
#ifdef ZTS
	v8js_globals->extensions = NULL;
	v8js_globals->v8_initialized = 0;
	v8js_globals->v8_flags = NULL;

	v8js_globals->timer_thread = NULL;
	v8js_globals->timer_stop = false;
	new(&v8js_globals->timer_mutex) std::mutex;
	new(&v8js_globals->timer_stack) std::deque<v8js_timer_ctx *>;

	v8js_globals->fatal_error_abort = 0;
#endif
}
/* }}} */

/* {{{ PHP_GSHUTDOWN_FUNCTION
 */
static PHP_GSHUTDOWN_FUNCTION(v8js)
{
	if (v8js_globals->extensions) {
		zend_hash_destroy(v8js_globals->extensions);
		free(v8js_globals->extensions);
		v8js_globals->extensions = NULL;
	}

	if (v8js_globals->v8_flags) {
		free(v8js_globals->v8_flags);
		v8js_globals->v8_flags = NULL;
	}

#ifdef ZTS
	v8js_globals->timer_stack.~deque();
	v8js_globals->timer_mutex.~mutex();
#endif

	if (v8js_globals->v8_initialized) {
		v8::V8::Dispose();
#if !defined(_WIN32) && PHP_V8_API_VERSION >= 3029036
		v8::V8::ShutdownPlatform();
		delete v8js_globals->v8_platform;
#endif
	}
}
/* }}} */

/* {{{ v8js_functions[] */
static const zend_function_entry v8js_functions[] = {
	{NULL, NULL, NULL}
};
/* }}} */

/* {{{ v8js_module_entry
 */
zend_module_entry v8js_module_entry = {
	STANDARD_MODULE_HEADER_EX,
	NULL,
	NULL,
	"v8js",
	v8js_functions,
	PHP_MINIT(v8js),
	PHP_MSHUTDOWN(v8js),
	NULL,
	PHP_RSHUTDOWN(v8js),
	PHP_MINFO(v8js),
	PHP_V8JS_VERSION,
	PHP_MODULE_GLOBALS(v8js),
	PHP_GINIT(v8js),
	PHP_GSHUTDOWN(v8js),
	NULL,
	STANDARD_MODULE_PROPERTIES_EX
};
/* }}} */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */
<commit_msg>Refactor php.ini bool option parsing<commit_after>/*
  +----------------------------------------------------------------------+
  | PHP Version 5                                                        |
  +----------------------------------------------------------------------+
  | Copyright (c) 1997-2013 The PHP Group                                |
  +----------------------------------------------------------------------+
  | http://www.opensource.org/licenses/mit-license.php  MIT License      |
  +----------------------------------------------------------------------+
  | Author: Jani Taskinen <jani.taskinen@iki.fi>                         |
  | Author: Patrick Reilly <preilly@php.net>                             |
  +----------------------------------------------------------------------+
*/

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "php_v8js_macros.h"

extern "C" {
#include "php_ini.h"
#include "ext/standard/info.h"
#include "ext/standard/php_string.h"
#include "ext/standard/php_smart_str.h"
}

#include "v8js_class.h"
#include "v8js_exceptions.h"
#include "v8js_v8object_class.h"

ZEND_DECLARE_MODULE_GLOBALS(v8js)

/* {{{ INI Settings */

static ZEND_INI_MH(v8js_OnUpdateV8Flags) /* {{{ */
{
	if (new_value) {
		if (V8JSG(v8_flags)) {
			free(V8JSG(v8_flags));
			V8JSG(v8_flags) = NULL;
		}
		if (!new_value[0]) {
			return FAILURE;
		}
		V8JSG(v8_flags) = zend_strndup(new_value, new_value_length);
	}

	return SUCCESS;
}

static bool v8js_ini_to_bool(const char *new_value, uint new_value_length) /* {{{ */
{
	if (new_value_length == 2 && strcasecmp("on", new_value) == 0) {
		return true;
    } else if (new_value_length == 3 && strcasecmp("yes", new_value) == 0) {
		return true;
	} else if (new_value_length == 4 && strcasecmp("true", new_value) == 0) {
		return true;
	} else {
		return (bool) atoi(new_value);
	}
}
/* }}} */

static ZEND_INI_MH(v8js_OnUpdateUseDate) /* {{{ */
{
	V8JSG(use_date) = v8js_ini_to_bool(new_value, new_value_length);
	return SUCCESS;
}
/* }}} */

static ZEND_INI_MH(v8js_OnUpdateUseArrayAccess) /* {{{ */
{
	V8JSG(use_array_access) = v8js_ini_to_bool(new_value, new_value_length);
	return SUCCESS;
}
/* }}} */

static ZEND_INI_MH(v8js_OnUpdateCompatExceptions) /* {{{ */
{
	V8JSG(compat_php_exceptions) = v8js_ini_to_bool(new_value, new_value_length);
	return SUCCESS;
}
/* }}} */

ZEND_INI_BEGIN() /* {{{ */
	ZEND_INI_ENTRY("v8js.flags", NULL, ZEND_INI_ALL, v8js_OnUpdateV8Flags)
	ZEND_INI_ENTRY("v8js.use_date", "0", ZEND_INI_ALL, v8js_OnUpdateUseDate)
	ZEND_INI_ENTRY("v8js.use_array_access", "0", ZEND_INI_ALL, v8js_OnUpdateUseArrayAccess)
	ZEND_INI_ENTRY("v8js.compat_php_exceptions", "0", ZEND_INI_ALL, v8js_OnUpdateCompatExceptions)
ZEND_INI_END()
/* }}} */

/* }}} INI */

#ifdef COMPILE_DL_V8JS
ZEND_GET_MODULE(v8js)
#endif

/* {{{ PHP_MINIT_FUNCTION
 */
PHP_MINIT_FUNCTION(v8js)
{
	PHP_MINIT(v8js_class)(INIT_FUNC_ARGS_PASSTHRU);
	PHP_MINIT(v8js_exceptions)(INIT_FUNC_ARGS_PASSTHRU);
	PHP_MINIT(v8js_v8object_class)(INIT_FUNC_ARGS_PASSTHRU);

	REGISTER_INI_ENTRIES();

	return SUCCESS;
}
/* }}} */

/* {{{ PHP_MSHUTDOWN_FUNCTION
 */
static PHP_MSHUTDOWN_FUNCTION(v8js)
{
	UNREGISTER_INI_ENTRIES();
	return SUCCESS;
}
/* }}} */

/* {{{ PHP_RSHUTDOWN_FUNCTION
 */
static PHP_RSHUTDOWN_FUNCTION(v8js)
{
	// If the timer thread is running then stop it
	if (V8JSG(timer_thread)) {
		V8JSG(timer_stop) = true;
		V8JSG(timer_thread)->join();
		V8JSG(timer_stop) = false;
		delete V8JSG(timer_thread);
		V8JSG(timer_thread) = NULL;
	}

	return SUCCESS;
}
/* }}} */

/* {{{ PHP_MINFO_FUNCTION
 */
static PHP_MINFO_FUNCTION(v8js)
{
	php_info_print_table_start();
	php_info_print_table_header(2, "V8 Javascript Engine", "enabled");
	php_info_print_table_header(2, "V8 Engine Compiled Version", PHP_V8_VERSION);
	php_info_print_table_header(2, "V8 Engine Linked Version", v8::V8::GetVersion());
	php_info_print_table_header(2, "Version", PHP_V8JS_VERSION);
	php_info_print_table_end();

	DISPLAY_INI_ENTRIES();
}
/* }}} */

/* {{{ PHP_GINIT_FUNCTION
 */
static PHP_GINIT_FUNCTION(v8js)
{
	/*
	  If ZTS is disabled, the v8js_globals instance is declared right
	  in the BSS and hence automatically initialized by C++ compiler.
	  Most of the variables are just zeroed.

	  If ZTS is enabled however, v8js_globals just points to a freshly
	  allocated, uninitialized piece of memory, hence we need to
	  initialize all fields on our own.  Likewise on shutdown we have to
	  run the destructors manually.
	*/
#ifdef ZTS
	v8js_globals->extensions = NULL;
	v8js_globals->v8_initialized = 0;
	v8js_globals->v8_flags = NULL;

	v8js_globals->timer_thread = NULL;
	v8js_globals->timer_stop = false;
	new(&v8js_globals->timer_mutex) std::mutex;
	new(&v8js_globals->timer_stack) std::deque<v8js_timer_ctx *>;

	v8js_globals->fatal_error_abort = 0;
#endif
}
/* }}} */

/* {{{ PHP_GSHUTDOWN_FUNCTION
 */
static PHP_GSHUTDOWN_FUNCTION(v8js)
{
	if (v8js_globals->extensions) {
		zend_hash_destroy(v8js_globals->extensions);
		free(v8js_globals->extensions);
		v8js_globals->extensions = NULL;
	}

	if (v8js_globals->v8_flags) {
		free(v8js_globals->v8_flags);
		v8js_globals->v8_flags = NULL;
	}

#ifdef ZTS
	v8js_globals->timer_stack.~deque();
	v8js_globals->timer_mutex.~mutex();
#endif

	if (v8js_globals->v8_initialized) {
		v8::V8::Dispose();
#if !defined(_WIN32) && PHP_V8_API_VERSION >= 3029036
		v8::V8::ShutdownPlatform();
		delete v8js_globals->v8_platform;
#endif
	}
}
/* }}} */

/* {{{ v8js_functions[] */
static const zend_function_entry v8js_functions[] = {
	{NULL, NULL, NULL}
};
/* }}} */

/* {{{ v8js_module_entry
 */
zend_module_entry v8js_module_entry = {
	STANDARD_MODULE_HEADER_EX,
	NULL,
	NULL,
	"v8js",
	v8js_functions,
	PHP_MINIT(v8js),
	PHP_MSHUTDOWN(v8js),
	NULL,
	PHP_RSHUTDOWN(v8js),
	PHP_MINFO(v8js),
	PHP_V8JS_VERSION,
	PHP_MODULE_GLOBALS(v8js),
	PHP_GINIT(v8js),
	PHP_GSHUTDOWN(v8js),
	NULL,
	STANDARD_MODULE_PROPERTIES_EX
};
/* }}} */

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: noet sw=4 ts=4 fdm=marker
 * vim<600: noet sw=4 ts=4
 */
<|endoftext|>


<commit_before>#include "medActionsToolBox.h"

#include <QtGui>

#include <medDataManager.h>
#include <medAbstractDbController.h>
#include <medToolBoxBody.h>

class medActionsToolBoxPrivate
{
public:

    QWidget* buttonsWidget;
    QWidget* noButtonsSelectedWidget;

    QPushButton* removeBt;
    QPushButton* viewBt;
    QPushButton* exportBt;
    QPushButton* bookmarkBt;
    QPushButton* importBt;
    QPushButton* loadBt;
    QPushButton* indexBt;
    QPushButton* saveBt;

    QList<QAbstractButton*> buttonsList;
    QMultiMap<QString, QString> itemToActions;
};

medActionsToolBox::medActionsToolBox( QWidget *parent /*= 0*/ ) : medToolBox(parent), d(new medActionsToolBoxPrivate)
{
    /**
     * This toolbox will show possible action buttons depending on the
     * items that is currently selected in the file system or db browser.
     *
     * Which actions are appropriate to which item is specified in the itemToActions map.
     *
     * It consists of two widgets: one containing the buttons and another one
     * with an explanatory label telling the user that an item must be selected.
     * Both widgets' visibilities are set depending on the selection.
     */

    d->buttonsWidget = new QWidget(this);
    d->noButtonsSelectedWidget = new QWidget(this);

    initializeItemToActionsMap();

    /* Begin create buttons */

    d->removeBt = new QPushButton(d->buttonsWidget);
    d->removeBt->setAccessibleName("Remove");
    d->removeBt->setText(tr("Remove"));
    d->removeBt->setToolTip(tr("Remove selected item from the database."));
    d->removeBt->setIcon(QIcon(":/icons/cross.svg"));

    d->viewBt = new QPushButton(d->buttonsWidget);
    d->viewBt->setAccessibleName("View");
    d->viewBt->setText(tr("View"));
    d->viewBt->setToolTip(tr("Load and visualize the currently selected item."));
    d->viewBt->setIcon(QIcon(":/icons/eye.png"));

    d->exportBt = new QPushButton(d->buttonsWidget);
    d->exportBt->setAccessibleName("Export");
    d->exportBt->setText(tr("Export"));
    d->exportBt->setToolTip(tr("Export the series."));
    d->exportBt->setIcon(QIcon(":/icons/export.png"));

    d->importBt = new QPushButton(d->buttonsWidget);
    d->importBt->setAccessibleName("Import");
    d->importBt->setText(tr("Import"));
    d->importBt->setToolTip(tr("Import (copy) item(s) into medInria's database."));
    d->importBt->setIcon(QIcon(":/icons/import.png"));

    d->loadBt = new QPushButton(d->buttonsWidget);
    d->loadBt->setAccessibleName("Load");
    d->loadBt->setText(tr("Load"));
    d->loadBt->setToolTip(tr("Temporary load the item(s) so as they can be used inside medInria,\nbut do not include them in the database."));
    d->loadBt->setIcon(QIcon(":/icons/document-open.png"));

    d->indexBt = new QPushButton(d->buttonsWidget);
    d->indexBt->setAccessibleName("Index");
    d->indexBt->setText(tr("Index"));
    d->indexBt->setToolTip(tr("Include the item(s) into medInria's database but do not import (copy) them."));
    d->indexBt->setIcon(QIcon(":/icons/finger.png"));

    d->bookmarkBt = new QPushButton(d->buttonsWidget);
    d->bookmarkBt->setAccessibleName("Bookmark");
    d->bookmarkBt->setText(tr("Bookmark"));
    d->bookmarkBt->setToolTip(tr("Bookmark selected folder/resource."));
    d->bookmarkBt->setIcon(QIcon(":/icons/star.svg"));

    d->saveBt = new QPushButton(d->buttonsWidget);
    d->saveBt->setAccessibleName("Save");
    d->saveBt->setText(tr("Save"));
    d->saveBt->setToolTip(tr("Save selected item into the database."));
    d->saveBt->setIcon(QIcon(":/icons/save.png"));

    /* End create buttons */

    // the order of the buttons in this list determines the order used to place them in the grid layout
    d->buttonsList << d->viewBt << d->loadBt << d->importBt << d->indexBt;
    d->buttonsList << d->removeBt << d->exportBt << d->saveBt << d->bookmarkBt;

    int COLUMNS = 4; // we will use 2 rows of 4 buttons each
    int i = 0;
    QGridLayout *gridLayout = new QGridLayout(d->buttonsWidget);
    gridLayout->setHorizontalSpacing(4);

    foreach(QAbstractButton* bt, d->buttonsList)
    {
        bt->setAutoFillBackground(true);
        bt->setObjectName("actionToolBoxButton"); // set for style sheet medInria.qss
        gridLayout->addWidget(bt, (int)i/COLUMNS, (int)i%COLUMNS);
        i++;
    }

    this->addWidget(d->buttonsWidget);
    d->buttonsWidget->setVisible(false);

    QLabel* noButtonsSelectedLabel = new QLabel(
                tr("Select any item to see possible actions."),
                d->noButtonsSelectedWidget);
    noButtonsSelectedLabel->setObjectName("actionToolBoxLabel");
    // we use a layout to center the label
    QHBoxLayout* noButtonsSelectedLayout = new QHBoxLayout(d->noButtonsSelectedWidget);
    noButtonsSelectedLayout->addWidget(noButtonsSelectedLabel, 0, Qt::AlignCenter);
    this->addWidget(d->noButtonsSelectedWidget);

    connect(d->removeBt, SIGNAL(clicked()), this, SIGNAL(removeClicked()));
    connect(d->viewBt, SIGNAL(clicked()), this, SIGNAL(viewClicked()));
    connect(d->exportBt, SIGNAL(clicked()), this, SIGNAL(exportClicked()));
    connect(d->bookmarkBt, SIGNAL(clicked()), this, SIGNAL(bookmarkClicked()));
    connect(d->importBt, SIGNAL(clicked()), this, SIGNAL(importClicked()));
    connect(d->loadBt, SIGNAL(clicked()), this, SIGNAL(loadClicked()));
    connect(d->indexBt, SIGNAL(clicked()), this, SIGNAL(indexClicked()));
    connect(d->saveBt, SIGNAL(clicked()), this, SIGNAL(saveClicked()));

    // we keep the size of the toolbox fixed so as it doesn't not resize
    // constantly due to the exchange of the widgets
    this->body()->setFixedHeight(38 + 38 + 35);

    this->setTitle(tr("Actions"));
}

medActionsToolBox::~medActionsToolBox()
{
//    delete d->itemToActions;
//    d->itemToActions = NULL;
    delete d;
    d = NULL;
}

void medActionsToolBox::patientSelected(const medDataIndex& index)
{
    if( !(medDataManager::instance()->controllerForDataSource(index.dataSourceId())->isPersistent()) )
        updateButtons("Unsaved Patient");
    else
        updateButtons("Patient");
}

void medActionsToolBox::seriesSelected(const medDataIndex& index)
{
    if( !(medDataManager::instance()->controllerForDataSource(index.dataSourceId())->isPersistent()) )
        updateButtons("Unsaved Series");
    else
        updateButtons("Series");
}

void medActionsToolBox::noPatientOrSeriesSelected()
{
    updateButtons("None");
}

void medActionsToolBox::selectedPathsChanged(const QStringList& paths)
{
    bool containsFolders = false;
    bool containsFiles = false;

    foreach(QString path, paths)
    {
        QFileInfo fi(path);

        if (fi.isDir())
            containsFolders = true;
        else
            containsFiles = true;
    }

    if (containsFolders && containsFiles)
        updateButtons("Files & Folders");
    else if (containsFolders)
        updateButtons("Folders");
    else if (containsFiles)
        updateButtons("Files");
    else
        updateButtons("None");
}

void medActionsToolBox::updateButtons(QString selectedItem)
{
    QList<QString> actions = d->itemToActions.values(selectedItem);

    foreach(QAbstractButton* bt, d->buttonsList)
    {
        bt->setVisible(true);
        bool showButton = actions.contains( bt->accessibleName() );
        bt->setEnabled(showButton); // Not accessible buttons are disabled
    }

    // insert an explanatory label if no button is being displayed
    if(actions.size() == 0)
    {
        d->noButtonsSelectedWidget->setVisible(true);
        d->buttonsWidget->setVisible(false);
    }
    else
    {
        d->noButtonsSelectedWidget->setVisible(false);
        d->buttonsWidget->setVisible(true);
    }
}

void medActionsToolBox::initializeItemToActionsMap()
{
    d->itemToActions = QMultiMap<QString, QString>();

    d->itemToActions.insert("Patient", "Remove");

    d->itemToActions.insert("Unsaved Patient", "Remove");
    d->itemToActions.insert("Unsaved Patient", "Save");

    d->itemToActions.insert("Series", "View");
    d->itemToActions.insert("Series", "Export");
    d->itemToActions.insert("Series", "Remove");

    d->itemToActions.insert("Unsaved Series", "Remove");
    d->itemToActions.insert("Unsaved Series", "Save");
    d->itemToActions.insert("Unsaved Series", "View");
    d->itemToActions.insert("Unsaved Series", "Export");

    d->itemToActions.insert("Folders", "Bookmark");
    d->itemToActions.insert("Folders", "Import");
    d->itemToActions.insert("Folders", "Index");
    d->itemToActions.insert("Folders", "Load");
    d->itemToActions.insert("Folders", "View");

    d->itemToActions.insert("Files", "Import");
    d->itemToActions.insert("Files", "Index");
    d->itemToActions.insert("Files", "Load");
    d->itemToActions.insert("Files", "View");

    d->itemToActions.insert("Files & Folders", "Import");
    d->itemToActions.insert("Files & Folders", "Index");
    d->itemToActions.insert("Files & Folders", "Load");
    d->itemToActions.insert("Files & Folders", "View");
}
<commit_msg>Load/Save and Import/Export lined up<commit_after>#include "medActionsToolBox.h"

#include <QtGui>

#include <medDataManager.h>
#include <medAbstractDbController.h>
#include <medToolBoxBody.h>

class medActionsToolBoxPrivate
{
public:

    QWidget* buttonsWidget;
    QWidget* noButtonsSelectedWidget;

    QPushButton* removeBt;
    QPushButton* viewBt;
    QPushButton* exportBt;
    QPushButton* bookmarkBt;
    QPushButton* importBt;
    QPushButton* loadBt;
    QPushButton* indexBt;
    QPushButton* saveBt;

    QList<QAbstractButton*> buttonsList;
    QMultiMap<QString, QString> itemToActions;
};

medActionsToolBox::medActionsToolBox( QWidget *parent /*= 0*/ ) : medToolBox(parent), d(new medActionsToolBoxPrivate)
{
    /**
     * This toolbox will show possible action buttons depending on the
     * items that is currently selected in the file system or db browser.
     *
     * Which actions are appropriate to which item is specified in the itemToActions map.
     *
     * It consists of two widgets: one containing the buttons and another one
     * with an explanatory label telling the user that an item must be selected.
     * Both widgets' visibilities are set depending on the selection.
     */

    d->buttonsWidget = new QWidget(this);
    d->noButtonsSelectedWidget = new QWidget(this);

    initializeItemToActionsMap();

    /* Begin create buttons */

    d->removeBt = new QPushButton(d->buttonsWidget);
    d->removeBt->setAccessibleName("Remove");
    d->removeBt->setText(tr("Remove"));
    d->removeBt->setToolTip(tr("Remove selected item from the database."));
    d->removeBt->setIcon(QIcon(":/icons/cross.svg"));

    d->viewBt = new QPushButton(d->buttonsWidget);
    d->viewBt->setAccessibleName("View");
    d->viewBt->setText(tr("View"));
    d->viewBt->setToolTip(tr("Load and visualize the currently selected item."));
    d->viewBt->setIcon(QIcon(":/icons/eye.png"));

    d->exportBt = new QPushButton(d->buttonsWidget);
    d->exportBt->setAccessibleName("Export");
    d->exportBt->setText(tr("Export"));
    d->exportBt->setToolTip(tr("Export the series."));
    d->exportBt->setIcon(QIcon(":/icons/export.png"));

    d->importBt = new QPushButton(d->buttonsWidget);
    d->importBt->setAccessibleName("Import");
    d->importBt->setText(tr("Import"));
    d->importBt->setToolTip(tr("Import (copy) item(s) into medInria's database."));
    d->importBt->setIcon(QIcon(":/icons/import.png"));

    d->loadBt = new QPushButton(d->buttonsWidget);
    d->loadBt->setAccessibleName("Load");
    d->loadBt->setText(tr("Load"));
    d->loadBt->setToolTip(tr("Temporary load the item(s) so as they can be used inside medInria,\nbut do not include them in the database."));
    d->loadBt->setIcon(QIcon(":/icons/document-open.png"));

    d->indexBt = new QPushButton(d->buttonsWidget);
    d->indexBt->setAccessibleName("Index");
    d->indexBt->setText(tr("Index"));
    d->indexBt->setToolTip(tr("Include the item(s) into medInria's database but do not import (copy) them."));
    d->indexBt->setIcon(QIcon(":/icons/finger.png"));

    d->bookmarkBt = new QPushButton(d->buttonsWidget);
    d->bookmarkBt->setAccessibleName("Bookmark");
    d->bookmarkBt->setText(tr("Bookmark"));
    d->bookmarkBt->setToolTip(tr("Bookmark selected folder/resource."));
    d->bookmarkBt->setIcon(QIcon(":/icons/star.svg"));

    d->saveBt = new QPushButton(d->buttonsWidget);
    d->saveBt->setAccessibleName("Save");
    d->saveBt->setText(tr("Save"));
    d->saveBt->setToolTip(tr("Save selected item into the database."));
    d->saveBt->setIcon(QIcon(":/icons/save.png"));

    /* End create buttons */

    // the order of the buttons in this list determines the order used to place them in the grid layout
    d->buttonsList << d->viewBt << d->loadBt << d->importBt << d->indexBt;
    d->buttonsList << d->removeBt << d->saveBt << d->exportBt << d->bookmarkBt;

    int COLUMNS = 4; // we will use 2 rows of 4 buttons each
    int i = 0;
    QGridLayout *gridLayout = new QGridLayout(d->buttonsWidget);
    gridLayout->setHorizontalSpacing(4);

    foreach(QAbstractButton* bt, d->buttonsList)
    {
        bt->setAutoFillBackground(true);
        bt->setObjectName("actionToolBoxButton"); // set for style sheet medInria.qss
        gridLayout->addWidget(bt, (int)i/COLUMNS, (int)i%COLUMNS);
        i++;
    }

    this->addWidget(d->buttonsWidget);
    d->buttonsWidget->setVisible(false);

    QLabel* noButtonsSelectedLabel = new QLabel(
                tr("Select any item to see possible actions."),
                d->noButtonsSelectedWidget);
    noButtonsSelectedLabel->setObjectName("actionToolBoxLabel");
    // we use a layout to center the label
    QHBoxLayout* noButtonsSelectedLayout = new QHBoxLayout(d->noButtonsSelectedWidget);
    noButtonsSelectedLayout->addWidget(noButtonsSelectedLabel, 0, Qt::AlignCenter);
    this->addWidget(d->noButtonsSelectedWidget);

    connect(d->removeBt, SIGNAL(clicked()), this, SIGNAL(removeClicked()));
    connect(d->viewBt, SIGNAL(clicked()), this, SIGNAL(viewClicked()));
    connect(d->exportBt, SIGNAL(clicked()), this, SIGNAL(exportClicked()));
    connect(d->bookmarkBt, SIGNAL(clicked()), this, SIGNAL(bookmarkClicked()));
    connect(d->importBt, SIGNAL(clicked()), this, SIGNAL(importClicked()));
    connect(d->loadBt, SIGNAL(clicked()), this, SIGNAL(loadClicked()));
    connect(d->indexBt, SIGNAL(clicked()), this, SIGNAL(indexClicked()));
    connect(d->saveBt, SIGNAL(clicked()), this, SIGNAL(saveClicked()));

    // we keep the size of the toolbox fixed so as it doesn't not resize
    // constantly due to the exchange of the widgets
    this->body()->setFixedHeight(38 + 38 + 35);

    this->setTitle(tr("Actions"));
}

medActionsToolBox::~medActionsToolBox()
{
//    delete d->itemToActions;
//    d->itemToActions = NULL;
    delete d;
    d = NULL;
}

void medActionsToolBox::patientSelected(const medDataIndex& index)
{
    if( !(medDataManager::instance()->controllerForDataSource(index.dataSourceId())->isPersistent()) )
        updateButtons("Unsaved Patient");
    else
        updateButtons("Patient");
}

void medActionsToolBox::seriesSelected(const medDataIndex& index)
{
    if( !(medDataManager::instance()->controllerForDataSource(index.dataSourceId())->isPersistent()) )
        updateButtons("Unsaved Series");
    else
        updateButtons("Series");
}

void medActionsToolBox::noPatientOrSeriesSelected()
{
    updateButtons("None");
}

void medActionsToolBox::selectedPathsChanged(const QStringList& paths)
{
    bool containsFolders = false;
    bool containsFiles = false;

    foreach(QString path, paths)
    {
        QFileInfo fi(path);

        if (fi.isDir())
            containsFolders = true;
        else
            containsFiles = true;
    }

    if (containsFolders && containsFiles)
        updateButtons("Files & Folders");
    else if (containsFolders)
        updateButtons("Folders");
    else if (containsFiles)
        updateButtons("Files");
    else
        updateButtons("None");
}

void medActionsToolBox::updateButtons(QString selectedItem)
{
    QList<QString> actions = d->itemToActions.values(selectedItem);

    foreach(QAbstractButton* bt, d->buttonsList)
    {
        bt->setVisible(true);
        bool showButton = actions.contains( bt->accessibleName() );
        bt->setEnabled(showButton); // Not accessible buttons are disabled
    }

    // insert an explanatory label if no button is being displayed
    if(actions.size() == 0)
    {
        d->noButtonsSelectedWidget->setVisible(true);
        d->buttonsWidget->setVisible(false);
    }
    else
    {
        d->noButtonsSelectedWidget->setVisible(false);
        d->buttonsWidget->setVisible(true);
    }
}

void medActionsToolBox::initializeItemToActionsMap()
{
    d->itemToActions = QMultiMap<QString, QString>();

    d->itemToActions.insert("Patient", "Remove");

    d->itemToActions.insert("Unsaved Patient", "Remove");
    d->itemToActions.insert("Unsaved Patient", "Save");

    d->itemToActions.insert("Series", "View");
    d->itemToActions.insert("Series", "Export");
    d->itemToActions.insert("Series", "Remove");

    d->itemToActions.insert("Unsaved Series", "Remove");
    d->itemToActions.insert("Unsaved Series", "Save");
    d->itemToActions.insert("Unsaved Series", "View");
    d->itemToActions.insert("Unsaved Series", "Export");

    d->itemToActions.insert("Folders", "Bookmark");
    d->itemToActions.insert("Folders", "Import");
    d->itemToActions.insert("Folders", "Index");
    d->itemToActions.insert("Folders", "Load");
    d->itemToActions.insert("Folders", "View");

    d->itemToActions.insert("Files", "Import");
    d->itemToActions.insert("Files", "Index");
    d->itemToActions.insert("Files", "Load");
    d->itemToActions.insert("Files", "View");

    d->itemToActions.insert("Files & Folders", "Import");
    d->itemToActions.insert("Files & Folders", "Index");
    d->itemToActions.insert("Files & Folders", "Load");
    d->itemToActions.insert("Files & Folders", "View");
}
<|endoftext|>


<commit_before>/*
	This file is part of cpp-ethereum.

	cpp-ethereum is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	cpp-ethereum 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 General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
*/
/** @file CodeModel.cpp
 * @author Arkadiy Paronyan arkadiy@ethdev.com
 * @date 2014
 * Ethereum IDE client.
 */

#include <sstream>
#include <memory>
#include <QDebug>
#include <QApplication>
#include <QtQml>
#include <libdevcore/SourceLocation.h>
#include <libsolidity/CompilerStack.h>
#include <libsolidity/SourceReferenceFormatter.h>
#include <libsolidity/InterfaceHandler.h>
#include <libevmcore/Instruction.h>
#include <libethcore/CommonJS.h>
#include "QContractDefinition.h"
#include "QFunctionDefinition.h"
#include "QVariableDeclaration.h"
#include "CodeHighlighter.h"
#include "FileIo.h"
#include "CodeModel.h"

using namespace dev::mix;

const std::set<std::string> c_predefinedContracts =
	{ "Config", "Coin", "CoinReg", "coin", "service", "owned", "mortal", "NameReg", "named", "std", "configUser" };

void BackgroundWorker::queueCodeChange(int _jobId)
{
	m_model->runCompilationJob(_jobId);
}

CompiledContract::CompiledContract(const dev::solidity::CompilerStack& _compiler, QString const& _contractName, QString const& _source):
	QObject(nullptr),
	m_sourceHash(qHash(_source))
{
	auto const& contractDefinition = _compiler.getContractDefinition(_contractName.toStdString());
	m_contract.reset(new QContractDefinition(&contractDefinition));
	QQmlEngine::setObjectOwnership(m_contract.get(), QQmlEngine::CppOwnership);
	m_bytes = _compiler.getBytecode(_contractName.toStdString());
	dev::solidity::InterfaceHandler interfaceHandler;
	m_contractInterface = QString::fromStdString(*interfaceHandler.getABIInterface(contractDefinition));
	if (m_contractInterface.isEmpty())
		m_contractInterface = "[]";
	if (contractDefinition.getLocation().sourceName.get())
		m_documentId = QString::fromStdString(*contractDefinition.getLocation().sourceName);
}

QString CompiledContract::codeHex() const
{
	return QString::fromStdString(toJS(m_bytes));
}

CodeModel::CodeModel(QObject* _parent):
	QObject(_parent),
	m_compiling(false),
	m_codeHighlighterSettings(new CodeHighlighterSettings()),
	m_backgroundWorker(this),
	m_backgroundJobId(0)
{
	m_backgroundThread.start();
	m_backgroundWorker.moveToThread(&m_backgroundThread);
	connect(this, &CodeModel::scheduleCompilationJob, &m_backgroundWorker, &BackgroundWorker::queueCodeChange, Qt::QueuedConnection);
	qRegisterMetaType<CompiledContract*>("CompiledContract*");
	qRegisterMetaType<QContractDefinition*>("QContractDefinition*");
	qRegisterMetaType<QFunctionDefinition*>("QFunctionDefinition*");
	qRegisterMetaType<QVariableDeclaration*>("QVariableDeclaration*");
	qmlRegisterType<QFunctionDefinition>("org.ethereum.qml", 1, 0, "QFunctionDefinition");
	qmlRegisterType<QVariableDeclaration>("org.ethereum.qml", 1, 0, "QVariableDeclaration");
}

CodeModel::~CodeModel()
{
	stop();
	disconnect(this);
	releaseContracts();
}

void CodeModel::stop()
{
	///@todo: cancel bg job
	m_backgroundThread.exit();
	m_backgroundThread.wait();
}

void CodeModel::reset(QVariantMap const& _documents)
{
	///@todo: cancel bg job
	Guard l(x_contractMap);
	releaseContracts();
	Guard pl(x_pendingContracts);
	m_pendingContracts.clear();

	for (QVariantMap::const_iterator d =  _documents.cbegin(); d != _documents.cend(); ++d)
		m_pendingContracts[d.key()] = d.value().toString();
	// launch the background thread
	m_compiling = true;
	emit stateChanged();
	emit scheduleCompilationJob(++m_backgroundJobId);
}

void CodeModel::registerCodeChange(QString const& _documentId, QString const& _code)
{
	{
		Guard l(x_contractMap);
		CompiledContract* contract = m_contractMap.value(_documentId);
		if (contract != nullptr && contract->m_sourceHash == qHash(_code))
			return;

		Guard pl(x_pendingContracts);
		m_pendingContracts[_documentId] = _code;
	}

	// launch the background thread
	m_compiling = true;
	emit stateChanged();
	emit scheduleCompilationJob(++m_backgroundJobId);
}

QVariantMap CodeModel::contracts() const
{
	QVariantMap result;
	Guard l(x_contractMap);
	for (ContractMap::const_iterator c = m_contractMap.cbegin(); c != m_contractMap.cend(); ++c)
		result.insert(c.key(), QVariant::fromValue(c.value()));
	return result;
}

CompiledContract* CodeModel::contractByDocumentId(QString _documentId) const
{
	Guard l(x_contractMap);
	for (ContractMap::const_iterator c = m_contractMap.cbegin(); c != m_contractMap.cend(); ++c)
		if (c.value()->m_documentId == _documentId)
			return c.value();
	return nullptr;
}

CompiledContract const& CodeModel::contract(QString _name) const
{
	Guard l(x_contractMap);
	CompiledContract* res = m_contractMap.value(_name);
	if (res == nullptr)
		BOOST_THROW_EXCEPTION(dev::Exception() << dev::errinfo_comment("Contract not found: " + _name.toStdString()));
	return *res;
}

void CodeModel::releaseContracts()
{
	for (ContractMap::iterator c = m_contractMap.begin(); c != m_contractMap.end(); ++c)
		c.value()->deleteLater();
	m_contractMap.clear();
}

void CodeModel::runCompilationJob(int _jobId)
{
	if (_jobId != m_backgroundJobId)
		return; //obsolete job

	ContractMap result;
	solidity::CompilerStack cs(true);
	try
	{
		cs.addSource("configUser", R"(contract configUser{function configAddr()constant returns(address a){ return 0xf025d81196b72fba60a1d4dddad12eeb8360d828;}})");
		{
			Guard l(x_pendingContracts);
			for (auto const& c: m_pendingContracts)
				cs.addSource(c.first.toStdString(), c.second.toStdString());
		}
		cs.compile(false);

		{
			Guard pl(x_pendingContracts);
			Guard l(x_contractMap);
			for (std::string n: cs.getContractNames())
			{
				if (c_predefinedContracts.count(n) != 0)
					continue;
				QString name = QString::fromStdString(n);
				auto sourceIter = m_pendingContracts.find(name);
				QString source = sourceIter != m_pendingContracts.end() ? sourceIter->second : QString();
				CompiledContract* contract = new CompiledContract(cs, name, source);
				QQmlEngine::setObjectOwnership(contract, QQmlEngine::CppOwnership);
				result[name] = contract;
				CompiledContract* prevContract = m_contractMap.value(name);
				if (prevContract != nullptr && prevContract->contractInterface() != result[name]->contractInterface())
					emit contractInterfaceChanged(name);
			}
			releaseContracts();
			m_contractMap.swap(result);
			emit codeChanged();
			emit compilationComplete();
		}
	}
	catch (dev::Exception const& _exception)
	{
		std::ostringstream error;
		solidity::SourceReferenceFormatter::printExceptionInformation(error, _exception, "Error", cs);
		SourceLocation const* location = boost::get_error_info<solidity::errinfo_sourceLocation>(_exception);
		QString message = QString::fromStdString(error.str());
		CompiledContract* contract = nullptr;
		if (location && location->sourceName.get() && (contract = contractByDocumentId(QString::fromStdString(*location->sourceName))))
			message = message.replace(QString::fromStdString(*location->sourceName), contract->contract()->name()); //substitute the location to match our contract names
		compilationError(message);
	}
	m_compiling = false;
	emit stateChanged();
}

bool CodeModel::hasContract() const
{
	Guard l(x_contractMap);
	return m_contractMap.size() != 0;
}

dev::bytes const& CodeModel::getStdContractCode(const QString& _contractName, const QString& _url)
{
	auto cached = m_compiledContracts.find(_contractName);
	if (cached != m_compiledContracts.end())
		return cached->second;

	FileIo fileIo;
	std::string source = fileIo.readFile(_url).toStdString();
	solidity::CompilerStack cs(false);
	cs.setSource(source);
	cs.compile(false);
	for (std::string const& name: cs.getContractNames())
	{
		dev::bytes code = cs.getBytecode(name);
		m_compiledContracts.insert(std::make_pair(QString::fromStdString(name), std::move(code)));
	}
	return m_compiledContracts.at(_contractName);
}

<commit_msg>Move SourceLocation to evmcore<commit_after>/*
	This file is part of cpp-ethereum.

	cpp-ethereum is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	cpp-ethereum 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 General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
*/
/** @file CodeModel.cpp
 * @author Arkadiy Paronyan arkadiy@ethdev.com
 * @date 2014
 * Ethereum IDE client.
 */

#include <sstream>
#include <memory>
#include <QDebug>
#include <QApplication>
#include <QtQml>
#include <libevmcore/SourceLocation.h>
#include <libsolidity/CompilerStack.h>
#include <libsolidity/SourceReferenceFormatter.h>
#include <libsolidity/InterfaceHandler.h>
#include <libevmcore/Instruction.h>
#include <libethcore/CommonJS.h>
#include "QContractDefinition.h"
#include "QFunctionDefinition.h"
#include "QVariableDeclaration.h"
#include "CodeHighlighter.h"
#include "FileIo.h"
#include "CodeModel.h"

using namespace dev::mix;

const std::set<std::string> c_predefinedContracts =
	{ "Config", "Coin", "CoinReg", "coin", "service", "owned", "mortal", "NameReg", "named", "std", "configUser" };

void BackgroundWorker::queueCodeChange(int _jobId)
{
	m_model->runCompilationJob(_jobId);
}

CompiledContract::CompiledContract(const dev::solidity::CompilerStack& _compiler, QString const& _contractName, QString const& _source):
	QObject(nullptr),
	m_sourceHash(qHash(_source))
{
	auto const& contractDefinition = _compiler.getContractDefinition(_contractName.toStdString());
	m_contract.reset(new QContractDefinition(&contractDefinition));
	QQmlEngine::setObjectOwnership(m_contract.get(), QQmlEngine::CppOwnership);
	m_bytes = _compiler.getBytecode(_contractName.toStdString());
	dev::solidity::InterfaceHandler interfaceHandler;
	m_contractInterface = QString::fromStdString(*interfaceHandler.getABIInterface(contractDefinition));
	if (m_contractInterface.isEmpty())
		m_contractInterface = "[]";
	if (contractDefinition.getLocation().sourceName.get())
		m_documentId = QString::fromStdString(*contractDefinition.getLocation().sourceName);
}

QString CompiledContract::codeHex() const
{
	return QString::fromStdString(toJS(m_bytes));
}

CodeModel::CodeModel(QObject* _parent):
	QObject(_parent),
	m_compiling(false),
	m_codeHighlighterSettings(new CodeHighlighterSettings()),
	m_backgroundWorker(this),
	m_backgroundJobId(0)
{
	m_backgroundThread.start();
	m_backgroundWorker.moveToThread(&m_backgroundThread);
	connect(this, &CodeModel::scheduleCompilationJob, &m_backgroundWorker, &BackgroundWorker::queueCodeChange, Qt::QueuedConnection);
	qRegisterMetaType<CompiledContract*>("CompiledContract*");
	qRegisterMetaType<QContractDefinition*>("QContractDefinition*");
	qRegisterMetaType<QFunctionDefinition*>("QFunctionDefinition*");
	qRegisterMetaType<QVariableDeclaration*>("QVariableDeclaration*");
	qmlRegisterType<QFunctionDefinition>("org.ethereum.qml", 1, 0, "QFunctionDefinition");
	qmlRegisterType<QVariableDeclaration>("org.ethereum.qml", 1, 0, "QVariableDeclaration");
}

CodeModel::~CodeModel()
{
	stop();
	disconnect(this);
	releaseContracts();
}

void CodeModel::stop()
{
	///@todo: cancel bg job
	m_backgroundThread.exit();
	m_backgroundThread.wait();
}

void CodeModel::reset(QVariantMap const& _documents)
{
	///@todo: cancel bg job
	Guard l(x_contractMap);
	releaseContracts();
	Guard pl(x_pendingContracts);
	m_pendingContracts.clear();

	for (QVariantMap::const_iterator d =  _documents.cbegin(); d != _documents.cend(); ++d)
		m_pendingContracts[d.key()] = d.value().toString();
	// launch the background thread
	m_compiling = true;
	emit stateChanged();
	emit scheduleCompilationJob(++m_backgroundJobId);
}

void CodeModel::registerCodeChange(QString const& _documentId, QString const& _code)
{
	{
		Guard l(x_contractMap);
		CompiledContract* contract = m_contractMap.value(_documentId);
		if (contract != nullptr && contract->m_sourceHash == qHash(_code))
			return;

		Guard pl(x_pendingContracts);
		m_pendingContracts[_documentId] = _code;
	}

	// launch the background thread
	m_compiling = true;
	emit stateChanged();
	emit scheduleCompilationJob(++m_backgroundJobId);
}

QVariantMap CodeModel::contracts() const
{
	QVariantMap result;
	Guard l(x_contractMap);
	for (ContractMap::const_iterator c = m_contractMap.cbegin(); c != m_contractMap.cend(); ++c)
		result.insert(c.key(), QVariant::fromValue(c.value()));
	return result;
}

CompiledContract* CodeModel::contractByDocumentId(QString _documentId) const
{
	Guard l(x_contractMap);
	for (ContractMap::const_iterator c = m_contractMap.cbegin(); c != m_contractMap.cend(); ++c)
		if (c.value()->m_documentId == _documentId)
			return c.value();
	return nullptr;
}

CompiledContract const& CodeModel::contract(QString _name) const
{
	Guard l(x_contractMap);
	CompiledContract* res = m_contractMap.value(_name);
	if (res == nullptr)
		BOOST_THROW_EXCEPTION(dev::Exception() << dev::errinfo_comment("Contract not found: " + _name.toStdString()));
	return *res;
}

void CodeModel::releaseContracts()
{
	for (ContractMap::iterator c = m_contractMap.begin(); c != m_contractMap.end(); ++c)
		c.value()->deleteLater();
	m_contractMap.clear();
}

void CodeModel::runCompilationJob(int _jobId)
{
	if (_jobId != m_backgroundJobId)
		return; //obsolete job

	ContractMap result;
	solidity::CompilerStack cs(true);
	try
	{
		cs.addSource("configUser", R"(contract configUser{function configAddr()constant returns(address a){ return 0xf025d81196b72fba60a1d4dddad12eeb8360d828;}})");
		{
			Guard l(x_pendingContracts);
			for (auto const& c: m_pendingContracts)
				cs.addSource(c.first.toStdString(), c.second.toStdString());
		}
		cs.compile(false);

		{
			Guard pl(x_pendingContracts);
			Guard l(x_contractMap);
			for (std::string n: cs.getContractNames())
			{
				if (c_predefinedContracts.count(n) != 0)
					continue;
				QString name = QString::fromStdString(n);
				auto sourceIter = m_pendingContracts.find(name);
				QString source = sourceIter != m_pendingContracts.end() ? sourceIter->second : QString();
				CompiledContract* contract = new CompiledContract(cs, name, source);
				QQmlEngine::setObjectOwnership(contract, QQmlEngine::CppOwnership);
				result[name] = contract;
				CompiledContract* prevContract = m_contractMap.value(name);
				if (prevContract != nullptr && prevContract->contractInterface() != result[name]->contractInterface())
					emit contractInterfaceChanged(name);
			}
			releaseContracts();
			m_contractMap.swap(result);
			emit codeChanged();
			emit compilationComplete();
		}
	}
	catch (dev::Exception const& _exception)
	{
		std::ostringstream error;
		solidity::SourceReferenceFormatter::printExceptionInformation(error, _exception, "Error", cs);
		SourceLocation const* location = boost::get_error_info<solidity::errinfo_sourceLocation>(_exception);
		QString message = QString::fromStdString(error.str());
		CompiledContract* contract = nullptr;
		if (location && location->sourceName.get() && (contract = contractByDocumentId(QString::fromStdString(*location->sourceName))))
			message = message.replace(QString::fromStdString(*location->sourceName), contract->contract()->name()); //substitute the location to match our contract names
		compilationError(message);
	}
	m_compiling = false;
	emit stateChanged();
}

bool CodeModel::hasContract() const
{
	Guard l(x_contractMap);
	return m_contractMap.size() != 0;
}

dev::bytes const& CodeModel::getStdContractCode(const QString& _contractName, const QString& _url)
{
	auto cached = m_compiledContracts.find(_contractName);
	if (cached != m_compiledContracts.end())
		return cached->second;

	FileIo fileIo;
	std::string source = fileIo.readFile(_url).toStdString();
	solidity::CompilerStack cs(false);
	cs.setSource(source);
	cs.compile(false);
	for (std::string const& name: cs.getContractNames())
	{
		dev::bytes code = cs.getBytecode(name);
		m_compiledContracts.insert(std::make_pair(QString::fromStdString(name), std::move(code)));
	}
	return m_compiledContracts.at(_contractName);
}

<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * 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 <sal/main.h>

#include <rtl/strbuf.hxx>

#include <libexslt/exslt.h>
#include <libxslt/transform.h>
#include <libxslt/xslt.h>
#include <libxslt/xsltutils.h>

#include <stdio.h>

#include "common.hxx"
#include "export.hxx"
#include "xrmmerge.hxx"
#include "tokens.h"
#include <iostream>
#include <fstream>
#include <vector>

rtl::OString sPrj;
rtl::OString sPrjRoot;
rtl::OString sInputFileName;
rtl::OString sOutputFile;

int extractTranslations()
{
    FILE *pOutFile = fopen(sOutputFile.getStr(), "w");
    if (!pOutFile)
    {
        fprintf(stderr, "cannot open %s\n", sOutputFile.getStr());
        return 1;
    }

    exsltRegisterAll();

    rtl::OString sActFileName = common::pathnameToken(sInputFileName.getStr(), sPrjRoot.getStr());

    rtl::OString sStyleSheet = rtl::OString(getenv("SRC_ROOT"))  + rtl::OString("/solenv/bin/uilangfilter.xslt");

    xsltStylesheetPtr stylesheet = xsltParseStylesheetFile ((const xmlChar *)sStyleSheet.getStr());

    xmlDocPtr doc = xmlParseFile(sInputFileName.getStr());

    xmlDocPtr res = xsltApplyStylesheet(stylesheet, doc, NULL);

    for( xmlNodePtr nodeLevel1 = res->children; nodeLevel1 != NULL; nodeLevel1 = nodeLevel1->next)
    {
        for( xmlNodePtr nodeLevel2 = nodeLevel1->children; nodeLevel2 != NULL; nodeLevel2 = nodeLevel2->next)
        {
            if (nodeLevel2->type == XML_ELEMENT_NODE)
            {
                fprintf(pOutFile, "%s\t%s\t0\t",sPrj.getStr(), sActFileName.getStr());
                for(xmlAttrPtr attribute = nodeLevel2->properties; attribute != NULL; attribute = attribute->next)
                {
                    xmlChar *content = xmlNodeListGetString(res, attribute->children, 1);
                    fprintf(pOutFile, "%s\t", content);
                    xmlFree(content);
                }
                fprintf(pOutFile, "\t\t0\ten-US\t%s\t\t\t\t\n", xmlNodeGetContent(nodeLevel2));
            }
        }
    }

    xmlFreeDoc(res);

    xmlFreeDoc(doc);

    xsltFreeStylesheet(stylesheet);

    fclose(pOutFile);

    return 0;
}

namespace
{
    rtl::OString QuotHTML(const rtl::OString &rString)
    {
        rtl::OStringBuffer sReturn;
        for (sal_Int32 i = 0; i < rString.getLength(); ++i) {
            switch (rString[i]) {
            case '\\':
                if (i < rString.getLength()) {
                    switch (rString[i + 1]) {
                    case '"':
                    case '<':
                    case '>':
                    case '\\':
                        ++i;
                        break;
                    }
                }
                // fall through
            default:
                sReturn.append(rString[i]);
                break;

            case '<':
                sReturn.append("<");
                break;

            case '>':
                sReturn.append(">");
                break;

            case '"':
                sReturn.append(""");
                break;

            case '&':
                if (rString.matchL(RTL_CONSTASCII_STRINGPARAM("&"), i))
                    sReturn.append('&');
                else
                    sReturn.append(RTL_CONSTASCII_STRINGPARAM("&"));
                break;
            }
        }
        return sReturn.makeStringAndClear();
    }
}

bool Merge(
    const rtl::OString &rSDFFile,
    const rtl::OString &rSourceFile,
    const rtl::OString &rDestinationFile)
{
    Export::InitLanguages( true );
    std::ofstream aDestination(
        rDestinationFile.getStr(), std::ios_base::out | std::ios_base::trunc);
    if (!aDestination.is_open()) {
        return false;
    }

    aDestination << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
    aDestination << "<t>\n";

    MergeDataFile aMergeDataFile( rSDFFile, rSourceFile, sal_False );
    rtl::OString sTmp( Export::sLanguages );
    if( sTmp.equalsIgnoreAsciiCaseL(RTL_CONSTASCII_STRINGPARAM("ALL")) )
        Export::SetLanguages( aMergeDataFile.GetLanguages() );

    std::vector<rtl::OString> aLanguages = Export::GetLanguages();

    const MergeDataHashMap& rMap = aMergeDataFile.getMap();

    for(size_t n = 0; n < aLanguages.size(); ++n)
    {
        rtl::OString sCur = aLanguages[ n ];
        if (sCur.isEmpty() || sCur.equalsIgnoreAsciiCaseL(RTL_CONSTASCII_STRINGPARAM("en-US")))
            continue;
        for (MergeDataHashMap::const_iterator aI = rMap.begin(), aEnd = rMap.end(); aI != aEnd; ++aI)
        {
            if (aI->second->sGID.isEmpty())
                continue;

            PFormEntrys* pFoo = aI->second->GetPFormEntries();
            rtl::OString sOut;
            pFoo->GetText( sOut, STRING_TYP_TEXT, sCur);

            if (sOut.isEmpty())
                continue;

            aDestination << " <e "
                << "g=\"" << aI->second->sGID.getStr() << "\" "
                << "i=\"" << aI->second->sLID.getStr() << "\">"
                << QuotHTML(sOut).getStr() << "</e>\n";
        }
    }

    aDestination << "</t>";
    aDestination.close();
    return sal_True;
}

SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, argv)
{
    int nRetValue = 0;

    HandledArgs aArgs;
    if ( !Export::handleArguments(argc, argv, aArgs) )
    {
        Export::writeUsage("uiex","ui");
        return 1;
    }

    sPrj = aArgs.m_sPrj;
    sPrjRoot = aArgs.m_sPrjRoot;
    sInputFileName = aArgs.m_sInputFile;
    sOutputFile = aArgs.m_sOutputFile;

    if (!aArgs.m_bMergeMode)
    {
        if (Export::sLanguages != "en-US")
        {
            fprintf(stderr, "only en-US can exist in source .ui files\n");
            nRetValue = 1;
        }
        else
            nRetValue = extractTranslations();
    }
    else
    {
        Merge(aArgs.m_sMergeSrc, sInputFileName, sOutputFile);
    }

    return nRetValue;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>drop unused include<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * 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 <sal/main.h>

#include <rtl/strbuf.hxx>

#include <libexslt/exslt.h>
#include <libxslt/transform.h>
#include <libxslt/xslt.h>
#include <libxslt/xsltutils.h>

#include <stdio.h>

#include "common.hxx"
#include "export.hxx"
#include "tokens.h"
#include <iostream>
#include <fstream>
#include <vector>

rtl::OString sPrj;
rtl::OString sPrjRoot;
rtl::OString sInputFileName;
rtl::OString sOutputFile;

int extractTranslations()
{
    FILE *pOutFile = fopen(sOutputFile.getStr(), "w");
    if (!pOutFile)
    {
        fprintf(stderr, "cannot open %s\n", sOutputFile.getStr());
        return 1;
    }

    exsltRegisterAll();

    rtl::OString sActFileName = common::pathnameToken(sInputFileName.getStr(), sPrjRoot.getStr());

    rtl::OString sStyleSheet = rtl::OString(getenv("SRC_ROOT"))  + rtl::OString("/solenv/bin/uilangfilter.xslt");

    xsltStylesheetPtr stylesheet = xsltParseStylesheetFile ((const xmlChar *)sStyleSheet.getStr());

    xmlDocPtr doc = xmlParseFile(sInputFileName.getStr());

    xmlDocPtr res = xsltApplyStylesheet(stylesheet, doc, NULL);

    for( xmlNodePtr nodeLevel1 = res->children; nodeLevel1 != NULL; nodeLevel1 = nodeLevel1->next)
    {
        for( xmlNodePtr nodeLevel2 = nodeLevel1->children; nodeLevel2 != NULL; nodeLevel2 = nodeLevel2->next)
        {
            if (nodeLevel2->type == XML_ELEMENT_NODE)
            {
                fprintf(pOutFile, "%s\t%s\t0\t",sPrj.getStr(), sActFileName.getStr());
                for(xmlAttrPtr attribute = nodeLevel2->properties; attribute != NULL; attribute = attribute->next)
                {
                    xmlChar *content = xmlNodeListGetString(res, attribute->children, 1);
                    fprintf(pOutFile, "%s\t", content);
                    xmlFree(content);
                }
                fprintf(pOutFile, "\t\t0\ten-US\t%s\t\t\t\t\n", xmlNodeGetContent(nodeLevel2));
            }
        }
    }

    xmlFreeDoc(res);

    xmlFreeDoc(doc);

    xsltFreeStylesheet(stylesheet);

    fclose(pOutFile);

    return 0;
}

namespace
{
    rtl::OString QuotHTML(const rtl::OString &rString)
    {
        rtl::OStringBuffer sReturn;
        for (sal_Int32 i = 0; i < rString.getLength(); ++i) {
            switch (rString[i]) {
            case '\\':
                if (i < rString.getLength()) {
                    switch (rString[i + 1]) {
                    case '"':
                    case '<':
                    case '>':
                    case '\\':
                        ++i;
                        break;
                    }
                }
                // fall through
            default:
                sReturn.append(rString[i]);
                break;

            case '<':
                sReturn.append("<");
                break;

            case '>':
                sReturn.append(">");
                break;

            case '"':
                sReturn.append(""");
                break;

            case '&':
                if (rString.matchL(RTL_CONSTASCII_STRINGPARAM("&"), i))
                    sReturn.append('&');
                else
                    sReturn.append(RTL_CONSTASCII_STRINGPARAM("&"));
                break;
            }
        }
        return sReturn.makeStringAndClear();
    }
}

bool Merge(
    const rtl::OString &rSDFFile,
    const rtl::OString &rSourceFile,
    const rtl::OString &rDestinationFile)
{
    Export::InitLanguages( true );
    std::ofstream aDestination(
        rDestinationFile.getStr(), std::ios_base::out | std::ios_base::trunc);
    if (!aDestination.is_open()) {
        return false;
    }

    aDestination << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
    aDestination << "<t>\n";

    MergeDataFile aMergeDataFile( rSDFFile, rSourceFile, sal_False );
    rtl::OString sTmp( Export::sLanguages );
    if( sTmp.equalsIgnoreAsciiCaseL(RTL_CONSTASCII_STRINGPARAM("ALL")) )
        Export::SetLanguages( aMergeDataFile.GetLanguages() );

    std::vector<rtl::OString> aLanguages = Export::GetLanguages();

    const MergeDataHashMap& rMap = aMergeDataFile.getMap();

    for(size_t n = 0; n < aLanguages.size(); ++n)
    {
        rtl::OString sCur = aLanguages[ n ];
        if (sCur.isEmpty() || sCur.equalsIgnoreAsciiCaseL(RTL_CONSTASCII_STRINGPARAM("en-US")))
            continue;
        for (MergeDataHashMap::const_iterator aI = rMap.begin(), aEnd = rMap.end(); aI != aEnd; ++aI)
        {
            if (aI->second->sGID.isEmpty())
                continue;

            PFormEntrys* pFoo = aI->second->GetPFormEntries();
            rtl::OString sOut;
            pFoo->GetText( sOut, STRING_TYP_TEXT, sCur);

            if (sOut.isEmpty())
                continue;

            aDestination << " <e "
                << "g=\"" << aI->second->sGID.getStr() << "\" "
                << "i=\"" << aI->second->sLID.getStr() << "\">"
                << QuotHTML(sOut).getStr() << "</e>\n";
        }
    }

    aDestination << "</t>";
    aDestination.close();
    return sal_True;
}

SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, argv)
{
    int nRetValue = 0;

    HandledArgs aArgs;
    if ( !Export::handleArguments(argc, argv, aArgs) )
    {
        Export::writeUsage("uiex","ui");
        return 1;
    }

    sPrj = aArgs.m_sPrj;
    sPrjRoot = aArgs.m_sPrjRoot;
    sInputFileName = aArgs.m_sInputFile;
    sOutputFile = aArgs.m_sOutputFile;

    if (!aArgs.m_bMergeMode)
    {
        if (Export::sLanguages != "en-US")
        {
            fprintf(stderr, "only en-US can exist in source .ui files\n");
            nRetValue = 1;
        }
        else
            nRetValue = extractTranslations();
    }
    else
    {
        Merge(aArgs.m_sMergeSrc, sInputFileName, sOutputFile);
    }

    return nRetValue;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>#include <mjolnir/potential/global/InversePowerPotential.hpp>

#ifdef MJOLNIR_SEPARATE_BUILD
#error "MJOLNIR_SEPARATE_BUILD flag is required"
#endif

namespace mjolnir
{
    template class InversePowerPotential<double>;
    template class InversePowerPotential<float>;
}// mjolnir
<commit_msg>fix: typo in macro for separate build<commit_after>#include <mjolnir/potential/global/InversePowerPotential.hpp>

#ifndef MJOLNIR_SEPARATE_BUILD
#error "MJOLNIR_SEPARATE_BUILD flag is required"
#endif

namespace mjolnir
{
    template class InversePowerPotential<double>;
    template class InversePowerPotential<float>;
}// mjolnir
<|endoftext|>


<commit_before><commit_msg>histogram destructor removed<commit_after><|endoftext|>