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

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

#include <rtl/ustrbuf.hxx>
#include <indexentrysupplier_asian.hxx>
#include <data/indexdata_alphanumeric.h>

using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::rtl;

namespace com { namespace sun { namespace star { namespace i18n {

extern "C" { static void SAL_CALL thisModule() {} }

IndexEntrySupplier_asian::IndexEntrySupplier_asian(
    const Reference < XMultiServiceFactory >& rxMSF ) : IndexEntrySupplier_Common(rxMSF)
{
    implementationName = "com.sun.star.i18n.IndexEntrySupplier_asian";
#ifdef SAL_DLLPREFIX
    OUString lib=OUString::createFromAscii(SAL_DLLPREFIX"index_data"SAL_DLLEXTENSION);
#else
    OUString lib=OUString::createFromAscii("index_data"SAL_DLLEXTENSION);
#endif
    hModule = osl_loadModuleRelative(
        &thisModule, lib.pData, SAL_LOADMODULE_DEFAULT );
}

IndexEntrySupplier_asian::~IndexEntrySupplier_asian()
{
    if (hModule) osl_unloadModule(hModule);
}

OUString SAL_CALL
IndexEntrySupplier_asian::getIndexCharacter( const OUString& rIndexEntry,
    const Locale& rLocale, const OUString& rAlgorithm ) throw (RuntimeException)
{
    sal_Int32 i=0;
    sal_uInt32 ch = rIndexEntry.iterateCodePoints(&i, 0);
    if (hModule) {
        OUString get=OUString::createFromAscii("get_indexdata_");
        sal_uInt16** (*func)(sal_Int16*)=NULL;
        if (rLocale.Language.equalsAscii("zh") && OUString::createFromAscii("TW HK MO").indexOf(rLocale.Country) >= 0)
            func=(sal_uInt16** (*)(sal_Int16*))osl_getFunctionSymbol(hModule, (get+rLocale.Language+OUString::createFromAscii("_TW_")+rAlgorithm).pData);
        if (!func)
            func=(sal_uInt16** (*)(sal_Int16*))osl_getFunctionSymbol(hModule, (get+rLocale.Language+OUString('_')+rAlgorithm).pData);
        if (func) {
            sal_Int16 max_index;
            sal_uInt16** idx=func(&max_index);
            if (((sal_Int16)(ch >> 8)) <= max_index) {
                sal_uInt16 address=idx[0][ch >> 8];
                if (address != 0xFFFF) {
                    address=idx[1][address+(ch & 0xFF)];
                    return idx[2] ? OUString(&idx[2][address]) : OUString(address);
                }
            }
        }
    }
    // using alphanumeric index for non-define stirng
    return OUString(&idxStr[(ch & 0xFFFFFF00) ? 0 : ch], 1);
}

OUString SAL_CALL
IndexEntrySupplier_asian::getIndexKey( const OUString& rIndexEntry,
    const OUString& rPhoneticEntry, const Locale& rLocale) throw (RuntimeException)
{
    return getIndexCharacter(getEntry(rIndexEntry, rPhoneticEntry, rLocale), rLocale, aAlgorithm);
}

sal_Int16 SAL_CALL
IndexEntrySupplier_asian::compareIndexEntry(
    const OUString& rIndexEntry1, const OUString& rPhoneticEntry1, const Locale& rLocale1,
    const OUString& rIndexEntry2, const OUString& rPhoneticEntry2, const Locale& rLocale2 )
    throw (RuntimeException)
{
    sal_Int32 result = collator->compareString(getEntry(rIndexEntry1, rPhoneticEntry1, rLocale1),
                                    getEntry(rIndexEntry2, rPhoneticEntry2, rLocale2));

    // equivalent of phonetic entries does not mean equivalent of index entries.
    // we have to continue comparing index entry here.
    if (result == 0 && usePhonetic && rPhoneticEntry1.getLength() > 0 &&
            rLocale1.Language == rLocale2.Language && rLocale1.Country == rLocale2.Country &&
            rLocale1.Variant == rLocale2.Variant)
        result = collator->compareString(rIndexEntry1, rIndexEntry2);
    return sal::static_int_cast< sal_Int16 >(result); // result in { -1, 0, 1 }
}

OUString SAL_CALL
IndexEntrySupplier_asian::getPhoneticCandidate( const OUString& rIndexEntry,
        const Locale& rLocale ) throw (RuntimeException)
{
    if (hModule) {
        sal_uInt16 **(*func)(sal_Int16*)=NULL;
        const sal_Char *func_name=NULL;
        if (rLocale.Language.equalsAscii("zh"))
            func_name=(OUString::createFromAscii("TW HK MO").indexOf(rLocale.Country) >= 0) ?  "get_zh_zhuyin" : "get_zh_pinyin";
        else if (rLocale.Language.equalsAscii("ko"))
            func_name="get_ko_phonetic";
        if (func_name)
            func=(sal_uInt16 **(*)(sal_Int16*))osl_getFunctionSymbol(hModule, OUString::createFromAscii(func_name).pData);
        if (func) {
            OUStringBuffer candidate;
            sal_Int16 max_index;
            sal_uInt16** idx=func(&max_index);
            OUString aIndexEntry=rIndexEntry;
            for (sal_Int32 i=0,j=0; i < rIndexEntry.getLength(); i=j) {
                sal_uInt32 ch = rIndexEntry.iterateCodePoints(&j, 1);
                if (((sal_Int16)(ch>>8)) <= max_index) {
                    sal_uInt16 address = idx[0][ch>>8];
                    if (address != 0xFFFF) {
                        address = idx[1][address + (ch & 0xFF)];
                        if (i > 0 && rLocale.Language.equalsAscii("zh"))
                            candidate.appendAscii(" ");
                        if (idx[2])
                            candidate.append(&idx[2][address]);
                        else
                            candidate.append(address);
                    } else
                        candidate.appendAscii(" ");
                }
            }
            return candidate.makeStringAndClear();
        }
    }
    return OUString();
}
} } } }
<commit_msg>INTEGRATION: CWS changefileheader (1.13.40); FILE MERGED 2008/03/31 16:01:23 rt 1.13.40.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: indexentrysupplier_asian.cxx,v $
 * $Revision: 1.14 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

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

#include <rtl/ustrbuf.hxx>
#include <indexentrysupplier_asian.hxx>
#include <data/indexdata_alphanumeric.h>

using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::rtl;

namespace com { namespace sun { namespace star { namespace i18n {

extern "C" { static void SAL_CALL thisModule() {} }

IndexEntrySupplier_asian::IndexEntrySupplier_asian(
    const Reference < XMultiServiceFactory >& rxMSF ) : IndexEntrySupplier_Common(rxMSF)
{
    implementationName = "com.sun.star.i18n.IndexEntrySupplier_asian";
#ifdef SAL_DLLPREFIX
    OUString lib=OUString::createFromAscii(SAL_DLLPREFIX"index_data"SAL_DLLEXTENSION);
#else
    OUString lib=OUString::createFromAscii("index_data"SAL_DLLEXTENSION);
#endif
    hModule = osl_loadModuleRelative(
        &thisModule, lib.pData, SAL_LOADMODULE_DEFAULT );
}

IndexEntrySupplier_asian::~IndexEntrySupplier_asian()
{
    if (hModule) osl_unloadModule(hModule);
}

OUString SAL_CALL
IndexEntrySupplier_asian::getIndexCharacter( const OUString& rIndexEntry,
    const Locale& rLocale, const OUString& rAlgorithm ) throw (RuntimeException)
{
    sal_Int32 i=0;
    sal_uInt32 ch = rIndexEntry.iterateCodePoints(&i, 0);
    if (hModule) {
        OUString get=OUString::createFromAscii("get_indexdata_");
        sal_uInt16** (*func)(sal_Int16*)=NULL;
        if (rLocale.Language.equalsAscii("zh") && OUString::createFromAscii("TW HK MO").indexOf(rLocale.Country) >= 0)
            func=(sal_uInt16** (*)(sal_Int16*))osl_getFunctionSymbol(hModule, (get+rLocale.Language+OUString::createFromAscii("_TW_")+rAlgorithm).pData);
        if (!func)
            func=(sal_uInt16** (*)(sal_Int16*))osl_getFunctionSymbol(hModule, (get+rLocale.Language+OUString('_')+rAlgorithm).pData);
        if (func) {
            sal_Int16 max_index;
            sal_uInt16** idx=func(&max_index);
            if (((sal_Int16)(ch >> 8)) <= max_index) {
                sal_uInt16 address=idx[0][ch >> 8];
                if (address != 0xFFFF) {
                    address=idx[1][address+(ch & 0xFF)];
                    return idx[2] ? OUString(&idx[2][address]) : OUString(address);
                }
            }
        }
    }
    // using alphanumeric index for non-define stirng
    return OUString(&idxStr[(ch & 0xFFFFFF00) ? 0 : ch], 1);
}

OUString SAL_CALL
IndexEntrySupplier_asian::getIndexKey( const OUString& rIndexEntry,
    const OUString& rPhoneticEntry, const Locale& rLocale) throw (RuntimeException)
{
    return getIndexCharacter(getEntry(rIndexEntry, rPhoneticEntry, rLocale), rLocale, aAlgorithm);
}

sal_Int16 SAL_CALL
IndexEntrySupplier_asian::compareIndexEntry(
    const OUString& rIndexEntry1, const OUString& rPhoneticEntry1, const Locale& rLocale1,
    const OUString& rIndexEntry2, const OUString& rPhoneticEntry2, const Locale& rLocale2 )
    throw (RuntimeException)
{
    sal_Int32 result = collator->compareString(getEntry(rIndexEntry1, rPhoneticEntry1, rLocale1),
                                    getEntry(rIndexEntry2, rPhoneticEntry2, rLocale2));

    // equivalent of phonetic entries does not mean equivalent of index entries.
    // we have to continue comparing index entry here.
    if (result == 0 && usePhonetic && rPhoneticEntry1.getLength() > 0 &&
            rLocale1.Language == rLocale2.Language && rLocale1.Country == rLocale2.Country &&
            rLocale1.Variant == rLocale2.Variant)
        result = collator->compareString(rIndexEntry1, rIndexEntry2);
    return sal::static_int_cast< sal_Int16 >(result); // result in { -1, 0, 1 }
}

OUString SAL_CALL
IndexEntrySupplier_asian::getPhoneticCandidate( const OUString& rIndexEntry,
        const Locale& rLocale ) throw (RuntimeException)
{
    if (hModule) {
        sal_uInt16 **(*func)(sal_Int16*)=NULL;
        const sal_Char *func_name=NULL;
        if (rLocale.Language.equalsAscii("zh"))
            func_name=(OUString::createFromAscii("TW HK MO").indexOf(rLocale.Country) >= 0) ?  "get_zh_zhuyin" : "get_zh_pinyin";
        else if (rLocale.Language.equalsAscii("ko"))
            func_name="get_ko_phonetic";
        if (func_name)
            func=(sal_uInt16 **(*)(sal_Int16*))osl_getFunctionSymbol(hModule, OUString::createFromAscii(func_name).pData);
        if (func) {
            OUStringBuffer candidate;
            sal_Int16 max_index;
            sal_uInt16** idx=func(&max_index);
            OUString aIndexEntry=rIndexEntry;
            for (sal_Int32 i=0,j=0; i < rIndexEntry.getLength(); i=j) {
                sal_uInt32 ch = rIndexEntry.iterateCodePoints(&j, 1);
                if (((sal_Int16)(ch>>8)) <= max_index) {
                    sal_uInt16 address = idx[0][ch>>8];
                    if (address != 0xFFFF) {
                        address = idx[1][address + (ch & 0xFF)];
                        if (i > 0 && rLocale.Language.equalsAscii("zh"))
                            candidate.appendAscii(" ");
                        if (idx[2])
                            candidate.append(&idx[2][address]);
                        else
                            candidate.append(address);
                    } else
                        candidate.appendAscii(" ");
                }
            }
            return candidate.makeStringAndClear();
        }
    }
    return OUString();
}
} } } }
<|endoftext|>


<commit_before>#ifndef VSMC_UTILITY_INTEGRATE_NUMERIC_NEWTON_COTES
#define VSMC_UTILITY_INTEGRATE_NUMERIC_NEWTON_COTES

#include <vsmc/internal/config.hpp>
#include <vsmc/internal/assert.hpp>
#include <vsmc/internal/defines.hpp>
#include <vsmc/internal/forward.hpp>

#include <vsmc/cxx11/functional.hpp>
#include <vsmc/cxx11/type_traits.hpp>

#include <cstddef>
#include <vector>

namespace vsmc { namespace internal {

template <unsigned Index, typename EvalType>
struct NumericNewtonCotesEval
{
    static double result (const double *coeff, double a, double h,
            const EvalType &eval)
    {
        return coeff[Index] * eval(a + (Index - 1) * h) +
            NumericNewtonCotesEval<Index - 1, EvalType>::
            result(coeff, a, h, eval);
    }
};

template <typename EvalType>
struct NumericNewtonCotesEval<1, EvalType>
{
    static double result (const double *coeff, double a, double h,
            const EvalType &eval)
    {
        return coeff[1] * eval(a);
    }
};

template <unsigned Degree>
class NumericNewtonCotesCoeff
{
    public :

    static NumericNewtonCotesCoeff<Degree> &instance ()
    {
        static NumericNewtonCotesCoeff<Degree> coeff;

        return coeff;
    }

    const double *coeff() const
    {
        return coeff_;
    }

    private :

    double coeff_[Degree + 2];

    NumericNewtonCotesCoeff ()
    { coeff_init(cxx11::integral_constant<unsigned, Degree>()); }

    NumericNewtonCotesCoeff
        (const NumericNewtonCotesCoeff<Degree> &);
    NumericNewtonCotesCoeff<Degree> &operator=
        (const NumericNewtonCotesCoeff<Degree> &);

    void coeff_init (cxx11::integral_constant<unsigned, 1>)
    {
        coeff_[0] = 0.5;
        coeff_[1] = 1;
        coeff_[2] = 1;
    }

    void coeff_init (cxx11::integral_constant<unsigned, 2>)
    {
        coeff_[0] = 1.0 / 6.0;
        coeff_[1] = 1;
        coeff_[2] = 4;
        coeff_[3] = 1;
    }

    void coeff_init (cxx11::integral_constant<unsigned, 3>)
    {
        coeff_[0] = 0.125;
        coeff_[1] = 1;
        coeff_[2] = 3;
        coeff_[3] = 3;
        coeff_[4] = 1;
    }

    void coeff_init (cxx11::integral_constant<unsigned, 4>)
    {
        coeff_[0] = 1.0 / 90.0;
        coeff_[1] = 7;
        coeff_[2] = 32;
        coeff_[3] = 12;
        coeff_[4] = 32;
        coeff_[5] = 7;
    }

    void coeff_init (cxx11::integral_constant<unsigned, 5>)
    {
        coeff_[0] = 1.0 / 288.0;
        coeff_[1] = 19;
        coeff_[2] = 75;
        coeff_[3] = 50;
        coeff_[4] = 50;
        coeff_[5] = 75;
        coeff_[6] = 19;
    }

    void coeff_init (cxx11::integral_constant<unsigned, 6>)
    {
        coeff_[0] = 1.0 / 840.0;
        coeff_[1] = 41;
        coeff_[2] = 216;
        coeff_[3] = 27;
        coeff_[4] = 272;
        coeff_[5] = 27;
        coeff_[6] = 216;
        coeff_[7] = 41;
    }

    void coeff_init (cxx11::integral_constant<unsigned, 7>)
    {
        coeff_[0] = 1.0 / 17280.0;
        coeff_[1] = 751;
        coeff_[2] = 3577;
        coeff_[3] = 1323;
        coeff_[4] = 2989;
        coeff_[5] = 2989;
        coeff_[6] = 1323;
        coeff_[7] = 3577;
        coeff_[8] = 751;
    }

    void coeff_init (cxx11::integral_constant<unsigned, 8>)
    {
        coeff_[0] = 1.0 / 28350.0;
        coeff_[1] = 989;
        coeff_[2] = 5888;
        coeff_[3] = -928;
        coeff_[4] = 10496;
        coeff_[5] = -4540;
        coeff_[6] = 10496;
        coeff_[7] = -928;
        coeff_[8] = 5888;
        coeff_[9] = 989;
    }

    void coeff_init (cxx11::integral_constant<unsigned, 9>)
    {
        coeff_[0] = 1.0 / 89600.0;
        coeff_[1] = 2857;
        coeff_[2] = 15741;
        coeff_[3] = 1080;
        coeff_[4] = 19344;
        coeff_[5] = 5778;
        coeff_[6] = 5778;
        coeff_[7] = 19344;
        coeff_[8] = 1080;
        coeff_[9] = 15741;
        coeff_[10] = 2857;
    }

    void coeff_init (cxx11::integral_constant<unsigned, 10>)
    {
        coeff_[0] = 1.0 / 598752.0;
        coeff_[1] = 16067;
        coeff_[2] = 106300;
        coeff_[3] = -48525;
        coeff_[4] = 272400;
        coeff_[5] = -260550;
        coeff_[6] = 427368;
        coeff_[7] = -260550;
        coeff_[8] = 272400;
        coeff_[9] = -48525;
        coeff_[10] = 106300;
        coeff_[11] = 16067;
    }
};

} } // namespace vsmc::internal

namespace vsmc { namespace integrate {

/// \brief Numerical integration with the (closed) Newton-Cotes formulae
/// \ingroup Integrate
template <unsigned Degree, template <typename> class NumericImpl>
class NumericNewtonCotes :
    public NumericImpl<NumericNewtonCotes<Degree, NumericImpl> >
{
    public :

    typedef NumericImpl<NumericNewtonCotes<Degree, NumericImpl> >
        integrate_impl_type;
    typedef typename integrate_impl_type::size_type size_type;
    typedef typename integrate_impl_type::eval_type eval_type;

    NumericNewtonCotes () :
        coeff_(internal::NumericNewtonCotesCoeff<Degree>::instance().coeff());
    {}

    double integrate_segment (double a, double b, const eval_type &eval) const
    {
        VSMC_STATIC_ASSERT_NUMERIC_NEWTON_COTES_DEGREE(Degree);

        double h = (b - a) / Degree;

        return coeff_[0] * (b - a) * (
                internal::NumericNewtonCotesEval<Degree, eval_type>::
                result(coeff_, a, h, eval) + coeff_[Degree + 1] * eval(b));
    }

    static VSMC_CONSTEXPR unsigned max_degree ()
    {
        return max_degree_;
    }

    private :

    static const unsigned max_degree_ = 10;
    const double *coeff_;
}; // class NumericNewtonCotes

} } // namespace vsmc::integrate

#endif // VSMC_UTILITY_NUMERIC_NEWTON_COTES
<commit_msg>fix typos<commit_after>#ifndef VSMC_UTILITY_INTEGRATE_NUMERIC_NEWTON_COTES
#define VSMC_UTILITY_INTEGRATE_NUMERIC_NEWTON_COTES

#include <vsmc/internal/config.hpp>
#include <vsmc/internal/assert.hpp>
#include <vsmc/internal/defines.hpp>
#include <vsmc/internal/forward.hpp>

#include <vsmc/cxx11/functional.hpp>
#include <vsmc/cxx11/type_traits.hpp>

#include <cstddef>
#include <vector>

namespace vsmc { namespace internal {

template <unsigned Index, typename EvalType>
struct NumericNewtonCotesEval
{
    static double result (const double *coeff, double a, double h,
            const EvalType &eval)
    {
        return coeff[Index] * eval(a + (Index - 1) * h) +
            NumericNewtonCotesEval<Index - 1, EvalType>::
            result(coeff, a, h, eval);
    }
};

template <typename EvalType>
struct NumericNewtonCotesEval<1, EvalType>
{
    static double result (const double *coeff, double a, double h,
            const EvalType &eval)
    {
        return coeff[1] * eval(a);
    }
};

template <unsigned Degree>
class NumericNewtonCotesCoeff
{
    public :

    static NumericNewtonCotesCoeff<Degree> &instance ()
    {
        static NumericNewtonCotesCoeff<Degree> coeff;

        return coeff;
    }

    const double *coeff() const
    {
        return coeff_;
    }

    private :

    double coeff_[Degree + 2];

    NumericNewtonCotesCoeff ()
    { coeff_init(cxx11::integral_constant<unsigned, Degree>()); }

    NumericNewtonCotesCoeff
        (const NumericNewtonCotesCoeff<Degree> &);
    NumericNewtonCotesCoeff<Degree> &operator=
        (const NumericNewtonCotesCoeff<Degree> &);

    void coeff_init (cxx11::integral_constant<unsigned, 1>)
    {
        coeff_[0] = 0.5;
        coeff_[1] = 1;
        coeff_[2] = 1;
    }

    void coeff_init (cxx11::integral_constant<unsigned, 2>)
    {
        coeff_[0] = 1.0 / 6.0;
        coeff_[1] = 1;
        coeff_[2] = 4;
        coeff_[3] = 1;
    }

    void coeff_init (cxx11::integral_constant<unsigned, 3>)
    {
        coeff_[0] = 0.125;
        coeff_[1] = 1;
        coeff_[2] = 3;
        coeff_[3] = 3;
        coeff_[4] = 1;
    }

    void coeff_init (cxx11::integral_constant<unsigned, 4>)
    {
        coeff_[0] = 1.0 / 90.0;
        coeff_[1] = 7;
        coeff_[2] = 32;
        coeff_[3] = 12;
        coeff_[4] = 32;
        coeff_[5] = 7;
    }

    void coeff_init (cxx11::integral_constant<unsigned, 5>)
    {
        coeff_[0] = 1.0 / 288.0;
        coeff_[1] = 19;
        coeff_[2] = 75;
        coeff_[3] = 50;
        coeff_[4] = 50;
        coeff_[5] = 75;
        coeff_[6] = 19;
    }

    void coeff_init (cxx11::integral_constant<unsigned, 6>)
    {
        coeff_[0] = 1.0 / 840.0;
        coeff_[1] = 41;
        coeff_[2] = 216;
        coeff_[3] = 27;
        coeff_[4] = 272;
        coeff_[5] = 27;
        coeff_[6] = 216;
        coeff_[7] = 41;
    }

    void coeff_init (cxx11::integral_constant<unsigned, 7>)
    {
        coeff_[0] = 1.0 / 17280.0;
        coeff_[1] = 751;
        coeff_[2] = 3577;
        coeff_[3] = 1323;
        coeff_[4] = 2989;
        coeff_[5] = 2989;
        coeff_[6] = 1323;
        coeff_[7] = 3577;
        coeff_[8] = 751;
    }

    void coeff_init (cxx11::integral_constant<unsigned, 8>)
    {
        coeff_[0] = 1.0 / 28350.0;
        coeff_[1] = 989;
        coeff_[2] = 5888;
        coeff_[3] = -928;
        coeff_[4] = 10496;
        coeff_[5] = -4540;
        coeff_[6] = 10496;
        coeff_[7] = -928;
        coeff_[8] = 5888;
        coeff_[9] = 989;
    }

    void coeff_init (cxx11::integral_constant<unsigned, 9>)
    {
        coeff_[0] = 1.0 / 89600.0;
        coeff_[1] = 2857;
        coeff_[2] = 15741;
        coeff_[3] = 1080;
        coeff_[4] = 19344;
        coeff_[5] = 5778;
        coeff_[6] = 5778;
        coeff_[7] = 19344;
        coeff_[8] = 1080;
        coeff_[9] = 15741;
        coeff_[10] = 2857;
    }

    void coeff_init (cxx11::integral_constant<unsigned, 10>)
    {
        coeff_[0] = 1.0 / 598752.0;
        coeff_[1] = 16067;
        coeff_[2] = 106300;
        coeff_[3] = -48525;
        coeff_[4] = 272400;
        coeff_[5] = -260550;
        coeff_[6] = 427368;
        coeff_[7] = -260550;
        coeff_[8] = 272400;
        coeff_[9] = -48525;
        coeff_[10] = 106300;
        coeff_[11] = 16067;
    }
};

} } // namespace vsmc::internal

namespace vsmc { namespace integrate {

/// \brief Numerical integration with the (closed) Newton-Cotes formulae
/// \ingroup Integrate
template <unsigned Degree, template <typename> class NumericImpl>
class NumericNewtonCotes :
    public NumericImpl<NumericNewtonCotes<Degree, NumericImpl> >
{
    public :

    typedef NumericImpl<NumericNewtonCotes<Degree, NumericImpl> >
        integrate_impl_type;
    typedef typename integrate_impl_type::size_type size_type;
    typedef typename integrate_impl_type::eval_type eval_type;

    NumericNewtonCotes () :
        coeff_(internal::NumericNewtonCotesCoeff<Degree>::instance().coeff())
    {}

    double integrate_segment (double a, double b, const eval_type &eval) const
    {
        VSMC_STATIC_ASSERT_NUMERIC_NEWTON_COTES_DEGREE(Degree);

        double h = (b - a) / Degree;

        return coeff_[0] * (b - a) * (
                internal::NumericNewtonCotesEval<Degree, eval_type>::
                result(coeff_, a, h, eval) + coeff_[Degree + 1] * eval(b));
    }

    static VSMC_CONSTEXPR unsigned max_degree ()
    {
        return max_degree_;
    }

    private :

    static const unsigned max_degree_ = 10;
    const double *coeff_;
}; // class NumericNewtonCotes

} } // namespace vsmc::integrate

#endif // VSMC_UTILITY_NUMERIC_NEWTON_COTES
<|endoftext|>


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

#include "qbsprojectmanager.h"

#include "defaultpropertyprovider.h"
#include "qbslogsink.h"
#include "qbsproject.h"
#include "qbsprojectmanagerconstants.h"
#include "qbsprojectmanagerplugin.h"

#include <coreplugin/messagemanager.h>
#include <extensionsystem/pluginmanager.h>
#include <projectexplorer/kit.h>
#include <projectexplorer/kitmanager.h>
#include <projectexplorer/projectexplorer.h>
#include <qmljstools/qmljstoolsconstants.h>
#include <qtsupport/baseqtversion.h>
#include <qtsupport/qtkitinformation.h>

#include <QVariantMap>

#include <qbs.h>
#include <qtprofilesetup.h>
#include <tools/profile.h> // TODO: Do this in qbs.h.

const QChar sep = QLatin1Char('.');

static QString qtcProfileGroup() { return QLatin1String("preferences.qtcreator.kit"); }
static QString qtcProfilePrefix() { return qtcProfileGroup() + sep; }

namespace QbsProjectManager {

qbs::Settings *QbsManager::m_settings = 0;

QbsManager::QbsManager(Internal::QbsProjectManagerPlugin *plugin) :
    m_plugin(plugin),
    m_defaultPropertyProvider(new DefaultPropertyProvider)
{
    m_settings = new qbs::Settings(QLatin1String("QtProject"), QLatin1String("qbs"));

    setObjectName(QLatin1String("QbsProjectManager"));
    connect(ProjectExplorer::KitManager::instance(), SIGNAL(kitsChanged()), this, SLOT(pushKitsToQbs()));

    m_logSink = new Internal::QbsLogSink(this);
    int level = qbs::LoggerWarning;
    const QString levelEnv = QString::fromLocal8Bit(qgetenv("QBS_LOG_LEVEL"));
    if (!levelEnv.isEmpty()) {
        bool ok = false;
        int tmp = levelEnv.toInt(&ok);
        if (ok) {
            if (tmp < static_cast<int>(qbs::LoggerMinLevel))
                tmp = static_cast<int>(qbs::LoggerMinLevel);
            if (tmp > static_cast<int>(qbs::LoggerMaxLevel))
                tmp = static_cast<int>(qbs::LoggerMaxLevel);
            level = tmp;
        }
    }
    m_logSink->setLogLevel(static_cast<qbs::LoggerLevel>(level));
}

QbsManager::~QbsManager()
{
    delete m_defaultPropertyProvider;
    delete m_settings;
}

QString QbsManager::mimeType() const
{
    return QLatin1String(QmlJSTools::Constants::QBS_MIMETYPE);
}

ProjectExplorer::Project *QbsManager::openProject(const QString &fileName, QString *errorString)
{
    if (!QFileInfo(fileName).isFile()) {
        if (errorString)
            *errorString = tr("Failed opening project '%1': Project is not a file")
                .arg(fileName);
        return 0;
    }

    return new Internal::QbsProject(this, fileName);
}

QString QbsManager::profileForKit(const ProjectExplorer::Kit *k) const
{
    if (!k)
        return QString();
    return m_settings->value(qtcProfilePrefix() + k->id().toString()).toString();
}

void QbsManager::setProfileForKit(const QString &name, const ProjectExplorer::Kit *k)
{
    m_settings->setValue(qtcProfilePrefix() + k->id().toString(), name);
}

qbs::Settings *QbsManager::settings()
{
    return m_settings;
}

void QbsManager::addProfile(const QString &name, const QVariantMap &data)
{
    qbs::Profile profile(name, settings());
    const QVariantMap::ConstIterator cend = data.constEnd();
    for (QVariantMap::ConstIterator it = data.constBegin(); it != cend; ++it)
        profile.setValue(it.key(), it.value());
}

void QbsManager::removeCreatorProfiles()
{
    foreach (const QString &key, m_settings->allKeysWithPrefix(qtcProfileGroup())) {
        const QString fullKey = qtcProfilePrefix() + key;
        qbs::Profile(m_settings->value(fullKey).toString(), m_settings).removeProfile();
        m_settings->remove(fullKey);
    }
}

void QbsManager::addQtProfileFromKit(const QString &profileName, const ProjectExplorer::Kit *k)
{
    const QtSupport::BaseQtVersion * const qt = QtSupport::QtKitInformation::qtVersion(k);
    if (!qt)
        return;

    qbs::QtEnvironment qtEnv;
    qtEnv.binaryPath = qt->binPath().toString();
    if (qt->hasDebugBuild())
        qtEnv.buildVariant << QLatin1String("debug");
    if (qt->hasReleaseBuild())
        qtEnv.buildVariant << QLatin1String("release");
    qtEnv.documentationPath = qt->docsPath().toString();
    qtEnv.includePath = qt->headerPath().toString();
    qtEnv.libraryPath = qt->libraryPath().toString();
    qtEnv.pluginPath = qt->pluginPath().toString();
    qtEnv.mkspecBasePath = qt->mkspecsPath().toString();
    qtEnv.mkspecName = qt->mkspec().toString();
    qtEnv.mkspecPath = qt->mkspecPath().toString();
    qtEnv.qtNameSpace = qt->qtNamespace();
    qtEnv.qtLibInfix = qt->qtLibInfix();
    qtEnv.qtVersion = qt->qtVersionString();
    qtEnv.frameworkBuild = qt->isFrameworkBuild();
    qtEnv.configItems = qt->configValues();
    qtEnv.qtConfigItems = qt->qtConfigValues();
    const qbs::ErrorInfo errorInfo = qbs::setupQtProfile(profileName, settings(), qtEnv);
    if (errorInfo.hasError()) {
        Core::MessageManager::write(tr("Failed to set up kit for qbs: %1")
                .arg(errorInfo.toString()), Core::MessageManager::ModeSwitch);
    }
}

void QbsManager::addProfileFromKit(const ProjectExplorer::Kit *k)
{
    const QString name = ProjectExplorer::Project::makeUnique(
                QString::fromLatin1("qtc_") + k->fileSystemFriendlyName(), m_settings->profiles());
    setProfileForKit(name, k);
    addQtProfileFromKit(name, k);

    // set up properties:
    QVariantMap data = m_defaultPropertyProvider->properties(k, QVariantMap());
    QList<PropertyProvider *> providerList = ExtensionSystem::PluginManager::getObjects<PropertyProvider>();
    foreach (PropertyProvider *provider, providerList) {
        if (provider->canHandle(k))
            data = provider->properties(k, data);
    }

    addProfile(name, data);
}

void QbsManager::pushKitsToQbs()
{
    // Get all keys
    removeCreatorProfiles();

    // add definitions from our kits
    foreach (const ProjectExplorer::Kit *k, ProjectExplorer::KitManager::kits())
        addProfileFromKit(k);
}

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

#include "qbsprojectmanager.h"

#include "defaultpropertyprovider.h"
#include "qbslogsink.h"
#include "qbsproject.h"
#include "qbsprojectmanagerconstants.h"
#include "qbsprojectmanagerplugin.h"

#include <coreplugin/messagemanager.h>
#include <extensionsystem/pluginmanager.h>
#include <projectexplorer/kit.h>
#include <projectexplorer/kitmanager.h>
#include <projectexplorer/projectexplorer.h>
#include <qmljstools/qmljstoolsconstants.h>
#include <qtsupport/baseqtversion.h>
#include <qtsupport/qtkitinformation.h>

#include <QVariantMap>

#include <qbs.h>
#include <qtprofilesetup.h>
#include <tools/profile.h> // TODO: Do this in qbs.h.

const QChar sep = QLatin1Char('.');

static QString qtcProfileGroup() { return QLatin1String("preferences.qtcreator.kit"); }
static QString qtcProfilePrefix() { return qtcProfileGroup() + sep; }

namespace QbsProjectManager {

qbs::Settings *QbsManager::m_settings = 0;

QbsManager::QbsManager(Internal::QbsProjectManagerPlugin *plugin) :
    m_plugin(plugin),
    m_defaultPropertyProvider(new DefaultPropertyProvider)
{
    m_settings = new qbs::Settings(QLatin1String("QtProject"), QLatin1String("qbs"));

    setObjectName(QLatin1String("QbsProjectManager"));
    connect(ProjectExplorer::KitManager::instance(), SIGNAL(kitsChanged()), this, SLOT(pushKitsToQbs()));

    m_logSink = new Internal::QbsLogSink(this);
    int level = qbs::LoggerWarning;
    const QString levelEnv = QString::fromLocal8Bit(qgetenv("QBS_LOG_LEVEL"));
    if (!levelEnv.isEmpty()) {
        bool ok = false;
        int tmp = levelEnv.toInt(&ok);
        if (ok) {
            if (tmp < static_cast<int>(qbs::LoggerMinLevel))
                tmp = static_cast<int>(qbs::LoggerMinLevel);
            if (tmp > static_cast<int>(qbs::LoggerMaxLevel))
                tmp = static_cast<int>(qbs::LoggerMaxLevel);
            level = tmp;
        }
    }
    m_logSink->setLogLevel(static_cast<qbs::LoggerLevel>(level));
}

QbsManager::~QbsManager()
{
    delete m_defaultPropertyProvider;
    delete m_settings;
}

QString QbsManager::mimeType() const
{
    return QLatin1String(QmlJSTools::Constants::QBS_MIMETYPE);
}

ProjectExplorer::Project *QbsManager::openProject(const QString &fileName, QString *errorString)
{
    if (!QFileInfo(fileName).isFile()) {
        if (errorString)
            *errorString = tr("Failed opening project '%1': Project is not a file")
                .arg(fileName);
        return 0;
    }

    return new Internal::QbsProject(this, fileName);
}

QString QbsManager::profileForKit(const ProjectExplorer::Kit *k) const
{
    if (!k)
        return QString();
    return m_settings->value(qtcProfilePrefix() + k->id().toString()).toString();
}

void QbsManager::setProfileForKit(const QString &name, const ProjectExplorer::Kit *k)
{
    m_settings->setValue(qtcProfilePrefix() + k->id().toString(), name);
}

qbs::Settings *QbsManager::settings()
{
    return m_settings;
}

void QbsManager::addProfile(const QString &name, const QVariantMap &data)
{
    qbs::Profile profile(name, settings());
    const QVariantMap::ConstIterator cend = data.constEnd();
    for (QVariantMap::ConstIterator it = data.constBegin(); it != cend; ++it)
        profile.setValue(it.key(), it.value());
}

void QbsManager::removeCreatorProfiles()
{
    foreach (const QString &key, m_settings->allKeysWithPrefix(qtcProfileGroup())) {
        const QString fullKey = qtcProfilePrefix() + key;
        qbs::Profile(m_settings->value(fullKey).toString(), m_settings).removeProfile();
        m_settings->remove(fullKey);
    }
}

void QbsManager::addQtProfileFromKit(const QString &profileName, const ProjectExplorer::Kit *k)
{
    const QtSupport::BaseQtVersion * const qt = QtSupport::QtKitInformation::qtVersion(k);
    if (!qt)
        return;

    qbs::QtEnvironment qtEnv;
    qtEnv.binaryPath = qt->binPath().toString();
    if (qt->hasDebugBuild())
        qtEnv.buildVariant << QLatin1String("debug");
    if (qt->hasReleaseBuild())
        qtEnv.buildVariant << QLatin1String("release");
    qtEnv.documentationPath = qt->docsPath().toString();
    qtEnv.includePath = qt->headerPath().toString();
    qtEnv.libraryPath = qt->libraryPath().toString();
    qtEnv.pluginPath = qt->pluginPath().toString();
    qtEnv.mkspecBasePath = qt->mkspecsPath().toString();
    qtEnv.mkspecName = qt->mkspec().toString();
    qtEnv.mkspecPath = qt->mkspecPath().toString();
    qtEnv.qtNameSpace = qt->qtNamespace();
    qtEnv.qtLibInfix = qt->qtLibInfix();
    qtEnv.qtVersion = qt->qtVersionString();
    qtEnv.qtMajorVersion = qt->qtVersion().majorVersion;
    qtEnv.qtMinorVersion = qt->qtVersion().minorVersion;
    qtEnv.qtPatchVersion = qt->qtVersion().patchVersion;
    qtEnv.frameworkBuild = qt->isFrameworkBuild();
    qtEnv.configItems = qt->configValues();
    qtEnv.qtConfigItems = qt->qtConfigValues();
    const qbs::ErrorInfo errorInfo = qbs::setupQtProfile(profileName, settings(), qtEnv);
    if (errorInfo.hasError()) {
        Core::MessageManager::write(tr("Failed to set up kit for qbs: %1")
                .arg(errorInfo.toString()), Core::MessageManager::ModeSwitch);
    }
}

void QbsManager::addProfileFromKit(const ProjectExplorer::Kit *k)
{
    const QString name = ProjectExplorer::Project::makeUnique(
                QString::fromLatin1("qtc_") + k->fileSystemFriendlyName(), m_settings->profiles());
    setProfileForKit(name, k);
    addQtProfileFromKit(name, k);

    // set up properties:
    QVariantMap data = m_defaultPropertyProvider->properties(k, QVariantMap());
    QList<PropertyProvider *> providerList = ExtensionSystem::PluginManager::getObjects<PropertyProvider>();
    foreach (PropertyProvider *provider, providerList) {
        if (provider->canHandle(k))
            data = provider->properties(k, data);
    }

    addProfile(name, data);
}

void QbsManager::pushKitsToQbs()
{
    // Get all keys
    removeCreatorProfiles();

    // add definitions from our kits
    foreach (const ProjectExplorer::Kit *k, ProjectExplorer::KitManager::kits())
        addProfileFromKit(k);
}

} // namespace QbsProjectManager
<|endoftext|>


<commit_before>/*ckwg +5
 * Copyright 2011 by Kitware, Inc. All Rights Reserved. Please refer to
 * KITWARE_LICENSE.TXT for licensing information, or contact General Counsel,
 * Kitware, Inc., 28 Corporate Drive, Clifton Park, NY 12065.
 */

#include "score_aggregation_process.h"

#include <vistk/pipeline/datum.h>

#include <vistk/scoring/scoring_result.h>

#include <boost/make_shared.hpp>

#include <numeric>

/**
 * \file score_aggregation_process.cxx
 *
 * \brief Implementation of the score aggregation process.
 */

namespace vistk
{

class score_aggregation_process::priv
{
  public:
    priv();
    ~priv();

    scoring_results_t results;

    static port_t const port_score;
    static port_t const port_aggregate;
};

process::port_t const score_aggregation_process::priv::port_score = process::port_t("score");
process::port_t const score_aggregation_process::priv::port_aggregate = process::port_t("aggregate");

score_aggregation_process
::score_aggregation_process(config_t const& config)
  : process(config)
  , d(new priv)
{
  // We only calculate on 'complete' datum.
  ensure_inputs_are_valid(false);

  port_flags_t required;

  required.insert(flag_required);

  declare_input_port(priv::port_score, boost::make_shared<port_info>(
    "score",
    required,
    port_description_t("The scores to aggregate.")));

  declare_output_port(priv::port_aggregate, boost::make_shared<port_info>(
    "score",
    required,
    port_description_t("The aggregate scores.")));
}

score_aggregation_process
::~score_aggregation_process()
{
}

void
score_aggregation_process
::_step()
{
  datum_t const dat = grab_datum_from_port(priv::port_score);

  bool complete = false;

  switch (dat->type())
  {
    case datum::complete:
      complete = true;
    case datum::flush:
    {
      scoring_result_t const base = boost::make_shared<scoring_result>(0, 0, 0);
      scoring_result_t const overall = std::accumulate(d->results.begin(), d->results.end(), base);

      push_to_port_as<scoring_result_t>(priv::port_aggregate, overall);

      break;
    }
    case datum::data:
    {
      scoring_result_t const result = dat->get_datum<scoring_result_t>();

      d->results.push_back(result);

      break;
    }
    case datum::invalid:
    case datum::empty:
    case datum::error:
    default:
      break;
  }

  if (complete)
  {
    mark_process_as_complete();
  }

  process::_step();
}

score_aggregation_process::priv
::priv()
{
}

score_aggregation_process::priv
::~priv()
{
}

}
<commit_msg>Push a complete datum after final aggregation<commit_after>/*ckwg +5
 * Copyright 2011 by Kitware, Inc. All Rights Reserved. Please refer to
 * KITWARE_LICENSE.TXT for licensing information, or contact General Counsel,
 * Kitware, Inc., 28 Corporate Drive, Clifton Park, NY 12065.
 */

#include "score_aggregation_process.h"

#include <vistk/pipeline/datum.h>

#include <vistk/scoring/scoring_result.h>

#include <boost/make_shared.hpp>

#include <numeric>

/**
 * \file score_aggregation_process.cxx
 *
 * \brief Implementation of the score aggregation process.
 */

namespace vistk
{

class score_aggregation_process::priv
{
  public:
    priv();
    ~priv();

    scoring_results_t results;

    static port_t const port_score;
    static port_t const port_aggregate;
};

process::port_t const score_aggregation_process::priv::port_score = process::port_t("score");
process::port_t const score_aggregation_process::priv::port_aggregate = process::port_t("aggregate");

score_aggregation_process
::score_aggregation_process(config_t const& config)
  : process(config)
  , d(new priv)
{
  // We only calculate on 'complete' datum.
  ensure_inputs_are_valid(false);

  port_flags_t required;

  required.insert(flag_required);

  declare_input_port(priv::port_score, boost::make_shared<port_info>(
    "score",
    required,
    port_description_t("The scores to aggregate.")));

  declare_output_port(priv::port_aggregate, boost::make_shared<port_info>(
    "score",
    required,
    port_description_t("The aggregate scores.")));
}

score_aggregation_process
::~score_aggregation_process()
{
}

void
score_aggregation_process
::_step()
{
  datum_t const dat = grab_datum_from_port(priv::port_score);

  bool complete = false;

  switch (dat->type())
  {
    case datum::complete:
      complete = true;
    case datum::flush:
    {
      scoring_result_t const base = boost::make_shared<scoring_result>(0, 0, 0);
      scoring_result_t const overall = std::accumulate(d->results.begin(), d->results.end(), base);

      push_to_port_as<scoring_result_t>(priv::port_aggregate, overall);

      break;
    }
    case datum::data:
    {
      scoring_result_t const result = dat->get_datum<scoring_result_t>();

      d->results.push_back(result);

      break;
    }
    case datum::invalid:
    case datum::empty:
    case datum::error:
    default:
      break;
  }

  if (complete)
  {
    push_datum_to_port(priv::port_aggregate, datum::complete_datum());

    mark_process_as_complete();
  }

  process::_step();
}

score_aggregation_process::priv
::priv()
{
}

score_aggregation_process::priv
::~priv()
{
}

}
<|endoftext|>


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

#include "xeumeuleu_test_pch.h"
#include "xeumeuleu/xml.h"

using namespace mockpp;

// -----------------------------------------------------------------------------
// Name: copy_xistream_from_root_to_empty_xostream
// Created: MCO 2007-05-28
// -----------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE( copy_xistream_from_root_to_empty_xostream )
{
    xml::xistringstream xis( "<root/>" );
    xml::xostringstream xos;
    xos << xis;
    BOOST_CHECK_EQUAL( "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n"
                       "<root/>\n", xos.str() );
}

// -----------------------------------------------------------------------------
// Name: copy_xistream_with_prolog_from_root_to_empty_xostream
// Created: MCO 2007-05-28
// -----------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE( copy_xistream_with_prolog_from_root_to_empty_xostream )
{
    xml::xistringstream xis( "<?xml version='1.0' encoding='UTF-8' standalone='no' ?><root/>" );
    xml::xostringstream xos;
    xos << xis;
    BOOST_CHECK_EQUAL( "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n"
                       "<root/>\n", xos.str() );
}

// -----------------------------------------------------------------------------
// Name: copy_xistream_from_root_to_xostream
// Created: MCO 2007-05-28
// -----------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE( copy_xistream_from_root_to_xostream )
{
    xml::xistringstream xis( "<element/>" );
    xml::xostringstream xos;
    xos << xml::content( "root", xis );
    BOOST_CHECK_EQUAL( "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n"
                       "<root>\n"
                       "  <element/>\n"
                       "</root>\n", xos.str() );
}

// -----------------------------------------------------------------------------
// Name: copy_xistream_from_sub_element_to_xostream
// Created: MCO 2007-05-28
// -----------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE( element_to_xostream )
{
    xml::xistringstream xis( "<element><sub-element/></element>" );
    xis >> xml::start( "element" );
    xml::xostringstream xos;
    xos << xml::content( "root", xis );
    BOOST_CHECK_EQUAL( "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n"
                       "<root>\n"
                       "  <sub-element/>\n"
                       "</root>\n", xos.str() );
}

// -----------------------------------------------------------------------------
// Name: copy_xistream_from_optional_non_existing_element_to_xostream
// Created: MCO 2007-05-28
// -----------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE( copy_xistream_from_optional_non_existing_element_to_xostream )
{
    xml::xistringstream xis( "<element/>" );
    xis >> xml::start( "element" )
        >> xml::optional >> xml::start( "non existing element" );
    xml::xostringstream xos;
    xos << xml::content( "root", xis );
    BOOST_CHECK_EQUAL( "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n"
                       "<root/>\n", xos.str() );
}

// -----------------------------------------------------------------------------
// Name: copy_xistream_from_optional_to_xostream
// Created: MCO 2007-05-28
// -----------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE( copy_xistream_from_optional_to_xostream )
{
    xml::xistringstream xis( "<element/>" );
    xis >> xml::start( "element" )
        >> xml::optional;
    xml::xostringstream xos;
    xos << xml::content( "root", xis );
    BOOST_CHECK_EQUAL( "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n"
                       "<root/>\n", xos.str() );
}

// -----------------------------------------------------------------------------
// Name: copy_xistream_from_sub_element_to_xostream_removes_meaningless_empty_text_node
// Created: MCO 2007-05-28
// -----------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE( copy_xistream_from_sub_element_to_xostream_removes_meaningless_empty_text_node )
{
    xml::xistringstream xis( "<root>  <sub-element/></root>" );
    xis >> xml::start( "root" );
    xml::xostringstream xos;
    xos << xml::start( "root" ) << xis << xml::end;
    BOOST_CHECK_EQUAL( "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n"
                       "<root>\n"
                       "  <sub-element/>\n"
                       "</root>\n", xos.str() );
}

// -----------------------------------------------------------------------------
// Name: copy_xistream_from_sub_element_to_xostream_removes_meaningless_empty_text_sub_node
// Created: MCO 2007-05-28
// -----------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE( copy_xistream_from_sub_element_to_xostream_removes_meaningless_empty_text_sub_node )
{
    xml::xistringstream xis( "<root>"
                             "  <element>"
                             "  </element>"
                             "</root>" );
    xml::xostringstream xos;
    xos << xis ;
    BOOST_CHECK_EQUAL( "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n"
                       "<root>\n"
                       "  <element/>\n"
                       "</root>\n", xos.str() );
}
<commit_msg>Added test<commit_after>/*
 *   Copyright (c) 2006, Mathieu Champlon
 *   All rights reserved.
 *
 *   Redistribution  and use  in source  and binary  forms, with  or without
 *   modification, are permitted provided  that the following conditions are
 *   met :
 *
 *   . Redistributions  of  source  code  must  retain  the  above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   . Redistributions in  binary form  must reproduce  the above  copyright
 *     notice, this list of conditions  and the following disclaimer in  the
 *     documentation and/or other materials provided with the distribution.
 *
 *   . Neither  the name  of  the  copyright  holders  nor the names  of the
 *     contributors may be used to endorse  or promote products derived from
 *     this software without specific prior written permission.
 *
 *   THIS SOFTWARE  IS  PROVIDED  BY THE  COPYRIGHT HOLDERS  AND CONTRIBUTORS
 *   ``AS IS''  AND ANY  EXPRESS OR  IMPLIED WARRANTIES,  INCLUDING,  BUT NOT
 *   LIMITED TO, THE IMPLIED  WARRANTIES  OF MERCHANTABILITY AND  FITNESS FOR
 *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE THE COPYRIGHT
 *   OWNERS OR CONTRIBUTORS  BE LIABLE FOR ANY  DIRECT, INDIRECT, INCIDENTAL,
 *   SPECIAL,  EXEMPLARY,  OR  CONSEQUENTIAL   DAMAGES  (INCLUDING,  BUT  NOT
 *   LIMITED TO,  PROCUREMENT OF SUBSTITUTE  GOODS OR SERVICES;  LOSS OF USE,
 *   DATA, OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED  AND ON  ANY
 *   THEORY  OF  LIABILITY,  WHETHER IN  CONTRACT,  STRICT LIABILITY, OR TORT
 *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY  WAY  OUT OF  THE USE
 *   OF THIS SOFTWARE, EVEN  IF  ADVISED OF  THE POSSIBILITY  OF SUCH DAMAGE.
 */

#include "xeumeuleu_test_pch.h"
#include "xeumeuleu/xml.h"

using namespace mockpp;

// -----------------------------------------------------------------------------
// Name: copy_xistream_from_root_to_empty_xostream
// Created: MCO 2007-05-28
// -----------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE( copy_xistream_from_root_to_empty_xostream )
{
    xml::xistringstream xis( "<root/>" );
    xml::xostringstream xos;
    xos << xis;
    BOOST_CHECK_EQUAL( "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n"
                       "<root/>\n", xos.str() );
}

// -----------------------------------------------------------------------------
// Name: copy_xistream_with_prolog_from_root_to_empty_xostream
// Created: MCO 2007-05-28
// -----------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE( copy_xistream_with_prolog_from_root_to_empty_xostream )
{
    xml::xistringstream xis( "<?xml version='1.0' encoding='UTF-8' standalone='no' ?><root/>" );
    xml::xostringstream xos;
    xos << xis;
    BOOST_CHECK_EQUAL( "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n"
                       "<root/>\n", xos.str() );
}

// -----------------------------------------------------------------------------
// Name: copy_xistream_from_root_to_xostream
// Created: MCO 2007-05-28
// -----------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE( copy_xistream_from_root_to_xostream )
{
    xml::xistringstream xis( "<element/>" );
    xml::xostringstream xos;
    xos << xml::content( "root", xis );
    BOOST_CHECK_EQUAL( "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n"
                       "<root>\n"
                       "  <element/>\n"
                       "</root>\n", xos.str() );
}

// -----------------------------------------------------------------------------
// Name: copy_xistream_from_sub_element_to_xostream
// Created: MCO 2007-05-28
// -----------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE( copy_xistream_from_sub_element_to_xostream )
{
    xml::xistringstream xis( "<element>"
                               "<sub-element/>"
                             "</element>" );
    xis >> xml::start( "element" );
    xml::xostringstream xos;
    xos << xml::content( "root", xis );
    BOOST_CHECK_EQUAL( "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n"
                       "<root>\n"
                       "  <sub-element/>\n"
                       "</root>\n", xos.str() );
}

// -----------------------------------------------------------------------------
// Name: copy_xistream_from_sub_elements_to_xostream_root_throws
// Created: MCO 2008-11-22
// -----------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE( copy_xistream_from_sub_elements_to_xostream_root_throws )
{
    xml::xistringstream xis( "<element>"
                               "<sub-element/>"
                               "<sub-element/>"
                             "</element>" );
    xis >> xml::start( "element" );
    xml::xostringstream xos;
    BOOST_CHECK_THROW( xos << xis, xml::exception );
}

// -----------------------------------------------------------------------------
// Name: copy_xistream_from_optional_non_existing_element_to_xostream
// Created: MCO 2007-05-28
// -----------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE( copy_xistream_from_optional_non_existing_element_to_xostream )
{
    xml::xistringstream xis( "<element/>" );
    xis >> xml::start( "element" )
        >> xml::optional >> xml::start( "non existing element" );
    xml::xostringstream xos;
    xos << xml::content( "root", xis );
    BOOST_CHECK_EQUAL( "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n"
                       "<root/>\n", xos.str() );
}

// -----------------------------------------------------------------------------
// Name: copy_xistream_from_optional_to_xostream
// Created: MCO 2007-05-28
// -----------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE( copy_xistream_from_optional_to_xostream )
{
    xml::xistringstream xis( "<element/>" );
    xis >> xml::start( "element" )
        >> xml::optional;
    xml::xostringstream xos;
    xos << xml::content( "root", xis );
    BOOST_CHECK_EQUAL( "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n"
                       "<root/>\n", xos.str() );
}

// -----------------------------------------------------------------------------
// Name: copy_xistream_from_sub_element_to_xostream_removes_meaningless_empty_text_node
// Created: MCO 2007-05-28
// -----------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE( copy_xistream_from_sub_element_to_xostream_removes_meaningless_empty_text_node )
{
    xml::xistringstream xis( "<root>  <sub-element/></root>" );
    xis >> xml::start( "root" );
    xml::xostringstream xos;
    xos << xml::start( "root" ) << xis << xml::end;
    BOOST_CHECK_EQUAL( "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n"
                       "<root>\n"
                       "  <sub-element/>\n"
                       "</root>\n", xos.str() );
}

// -----------------------------------------------------------------------------
// Name: copy_xistream_from_sub_element_to_xostream_removes_meaningless_empty_text_sub_node
// Created: MCO 2007-05-28
// -----------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE( copy_xistream_from_sub_element_to_xostream_removes_meaningless_empty_text_sub_node )
{
    xml::xistringstream xis( "<root>"
                             "  <element>"
                             "  </element>"
                             "</root>" );
    xml::xostringstream xos;
    xos << xis ;
    BOOST_CHECK_EQUAL( "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n"
                       "<root>\n"
                       "  <element/>\n"
                       "</root>\n", xos.str() );
}
<|endoftext|>


<commit_before>/*
Copyright (c) 2016 AscEmu Team <http://www.ascemu.org/>
This file is released under the MIT license. See README-MIT for more information.
*/

#ifndef _MOVEMENT_SPLINE_DEFINES_HPP
#define _MOVEMENT_SPLINE_DEFINES_HPP

#include "StdAfx.h"
#include "MovementSpline.hpp"

namespace Movement
{
    namespace Spline
    {
        enum SplineFlagsEnum
        {
            /* The first 4 bytes of the SplineFlags are actually an animation id
             * So the structure is:
             * uint8: anim_id
             * uint24: spline_flags
             *
             * ok i guess */
            SPLINEFLAG_DONE = 0x00000100,
            SPLINEFLAG_FALLING = 0x00000200,
            SPLINEFLAG_NO_SPLINE = 0x00000400,
            SPLINEFLAG_TRAJECTORY = 0x00000800,
            SPLINEFLAG_WALKMODE = 0x00001000,
            SPLINEFLAG_FLYING = 0x00002000,
            SPLINEFLAG_KNOCKBACK = 0x00004000,
            SPLINEFLAG_FINALPOINT = 0x00008000,
            SPLINEFLAG_FINALTARGET = 0x00010000,
            SPLINEFLAG_FINALANGLE = 0x00020000,
            SPLINEFLAG_CATMULLROM = 0x00040000,
            SPLINEFLAG_UNKNOWN1 = 0x00080000,
            SPLINEFLAG_UNKNOWN2 = 0x00100000,
            SPLINEFLAG_UNKNOWN3 = 0x00200000,
            SPLINEFLAG_UNKNOWN4 = 0x00400000,
            SPLINEFLAG_UNKNOWN5 = 0x00800000,
            SPLINEFLAG_UNKNOWN6 = 0x01000000,
            SPLINEFLAG_UNKNOWN7 = 0x02000000,
            SPLINEFLAG_UNKNOWN8 = 0x04000000,
            SPLINEFLAG_UNKNOWN9 = 0x08000000,
            SPLINEFLAG_UNKNOWN10 = 0x10000000,
            SPLINEFLAG_UNKNOWN11 = 0x20000000,
            SPLINEFLAG_UNKNOWN12 = 0x40000000
        };

        enum MonsterMoveType : uint8
        {
            MonsterMoveNormal = 0,
            MonsterMoveStop = 1,
            MonsterMoveFacingLocation = 2,
            MonsterMoveFacingTarget = 3,
            MonsterMoveFacingAngle = 4,
            MonsterMoveInvalid = 0xff,
        };

        /* NOT ALL DATA FIELDS IN THIS STRUCT ARE FILLED
         *
         * Read the MoveFlag to calculate which fields are filled */
        struct MonsterMoveFaceType
        {
            public:

                MonsterMoveFaceType() { MoveFlag = MonsterMoveInvalid; }

                uint8 GetFlag() { return MoveFlag; }
                void SetFlag(uint8 pFlag) { MoveFlag = pFlag; }

                /* MonsterMoveFacingLocation */
                float GetX() { return TargetPointX; }
                float GetY() { return TargetPointY; }
                float GetZ() { return TargetPointZ; }
                void SetX(float pX) { TargetPointX = pX; }
                void SetY(float pY) { TargetPointY = pY; }
                void SetZ(float pZ) { TargetPointZ = pZ; }

                /* MonsterMoveFacingTarget */
                uint64 GetGuid() { return TargetGuid; }
                void SetGuid(uint64 pGuid) { TargetGuid = pGuid; }

                /* MonsterMoveFacingAngle */
                float GetAngle() { return TargetAngle; }
                void SetAngle(float pAngle) { TargetAngle = pAngle; }

            protected:

                uint8 MoveFlag;

                /* MonsterMoveNormal */

                /* MonsterMoveStop */

                /* MonsterMoveFacingLocation */
                float TargetPointX;
                float TargetPointY;
                float TargetPointZ;

                /* MonsterMoveFacingTarget */
                uint64 TargetGuid;

                /* MonsterMoveFacingAngle */
                float TargetAngle;
        };

        struct SplineAnimation
        {
            bool IsAnimating;
            uint8 Id;
            int32 StartTime;
        };

        struct SplineParabolic
        {
            bool IsParabolic;
            float VerticalAcceleration;
            int32 StartTime;
        };
    }
}

#endif // _MOVEMENT_SPLINE_DEFINES_HPP
<commit_msg>Resolve CID 124943 (Uninitialized scalar field)<commit_after>/*
Copyright (c) 2016 AscEmu Team <http://www.ascemu.org/>
This file is released under the MIT license. See README-MIT for more information.
*/

#ifndef _MOVEMENT_SPLINE_DEFINES_HPP
#define _MOVEMENT_SPLINE_DEFINES_HPP

#include "StdAfx.h"
#include "MovementSpline.hpp"

namespace Movement
{
    namespace Spline
    {
        enum SplineFlagsEnum
        {
            /* The first 4 bytes of the SplineFlags are actually an animation id
             * So the structure is:
             * uint8: anim_id
             * uint24: spline_flags
             *
             * ok i guess */
            SPLINEFLAG_DONE = 0x00000100,
            SPLINEFLAG_FALLING = 0x00000200,
            SPLINEFLAG_NO_SPLINE = 0x00000400,
            SPLINEFLAG_TRAJECTORY = 0x00000800,
            SPLINEFLAG_WALKMODE = 0x00001000,
            SPLINEFLAG_FLYING = 0x00002000,
            SPLINEFLAG_KNOCKBACK = 0x00004000,
            SPLINEFLAG_FINALPOINT = 0x00008000,
            SPLINEFLAG_FINALTARGET = 0x00010000,
            SPLINEFLAG_FINALANGLE = 0x00020000,
            SPLINEFLAG_CATMULLROM = 0x00040000,
            SPLINEFLAG_UNKNOWN1 = 0x00080000,
            SPLINEFLAG_UNKNOWN2 = 0x00100000,
            SPLINEFLAG_UNKNOWN3 = 0x00200000,
            SPLINEFLAG_UNKNOWN4 = 0x00400000,
            SPLINEFLAG_UNKNOWN5 = 0x00800000,
            SPLINEFLAG_UNKNOWN6 = 0x01000000,
            SPLINEFLAG_UNKNOWN7 = 0x02000000,
            SPLINEFLAG_UNKNOWN8 = 0x04000000,
            SPLINEFLAG_UNKNOWN9 = 0x08000000,
            SPLINEFLAG_UNKNOWN10 = 0x10000000,
            SPLINEFLAG_UNKNOWN11 = 0x20000000,
            SPLINEFLAG_UNKNOWN12 = 0x40000000
        };

        enum MonsterMoveType : uint8
        {
            MonsterMoveNormal = 0,
            MonsterMoveStop = 1,
            MonsterMoveFacingLocation = 2,
            MonsterMoveFacingTarget = 3,
            MonsterMoveFacingAngle = 4,
            MonsterMoveInvalid = 0xff,
        };

        /* NOT ALL DATA FIELDS IN THIS STRUCT ARE FILLED
         *
         * Read the MoveFlag to calculate which fields are filled */
        struct MonsterMoveFaceType
        {
            public:

                MonsterMoveFaceType()
                {
                    MoveFlag = MonsterMoveInvalid;
                    TargetPointX = 0.0f;
                    TargetPointY = 0.0f;
                    TargetPointZ = 0.0f;
                    TargetGuid = 0;
                    TargetAngle = 0.0f;
                }

                uint8 GetFlag() { return MoveFlag; }
                void SetFlag(uint8 pFlag) { MoveFlag = pFlag; }

                /* MonsterMoveFacingLocation */
                float GetX() { return TargetPointX; }
                float GetY() { return TargetPointY; }
                float GetZ() { return TargetPointZ; }
                void SetX(float pX) { TargetPointX = pX; }
                void SetY(float pY) { TargetPointY = pY; }
                void SetZ(float pZ) { TargetPointZ = pZ; }

                /* MonsterMoveFacingTarget */
                uint64 GetGuid() { return TargetGuid; }
                void SetGuid(uint64 pGuid) { TargetGuid = pGuid; }

                /* MonsterMoveFacingAngle */
                float GetAngle() { return TargetAngle; }
                void SetAngle(float pAngle) { TargetAngle = pAngle; }

            protected:

                uint8 MoveFlag;

                /* MonsterMoveNormal */

                /* MonsterMoveStop */

                /* MonsterMoveFacingLocation */
                float TargetPointX;
                float TargetPointY;
                float TargetPointZ;

                /* MonsterMoveFacingTarget */
                uint64 TargetGuid;

                /* MonsterMoveFacingAngle */
                float TargetAngle;
        };

        struct SplineAnimation
        {
            bool IsAnimating;
            uint8 Id;
            int32 StartTime;
        };

        struct SplineParabolic
        {
            bool IsParabolic;
            float VerticalAcceleration;
            int32 StartTime;
        };
    }
}

#endif // _MOVEMENT_SPLINE_DEFINES_HPP
<|endoftext|>


<commit_before>//===--- RawComment.cpp - Extraction of raw comments ----------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file implements extraction of raw comments.
///
//===----------------------------------------------------------------------===//

#include "swift/AST/RawComment.h"
#include "swift/AST/Comment.h"
#include "swift/AST/ASTContext.h"
#include "swift/AST/Decl.h"
#include "swift/AST/Module.h"
#include "swift/AST/PrettyStackTrace.h"
#include "swift/Basic/PrimitiveParsing.h"
#include "swift/Basic/SourceManager.h"
#include "swift/Markup/Markup.h"
#include "swift/Parse/Lexer.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/raw_ostream.h"

using namespace swift;

static SingleRawComment::CommentKind getCommentKind(StringRef Comment) {
  assert(Comment.size() >= 2);
  assert(Comment[0] == '/');

  if (Comment[1] == '/') {
    if (Comment.size() < 3)
      return SingleRawComment::CommentKind::OrdinaryLine;

    if (Comment[2] == '/') {
      return SingleRawComment::CommentKind::LineDoc;
    }
    return SingleRawComment::CommentKind::OrdinaryLine;
  } else {
    assert(Comment[1] == '*');
    assert(Comment.size() >= 4);
    if (Comment[2] == '*') {
      return SingleRawComment::CommentKind::BlockDoc;
    }
    return SingleRawComment::CommentKind::OrdinaryBlock;
  }
}

SingleRawComment::SingleRawComment(CharSourceRange Range,
                                   const SourceManager &SourceMgr)
    : Range(Range), RawText(SourceMgr.extractText(Range)),
      Kind(static_cast<unsigned>(getCommentKind(RawText))),
      EndLine(SourceMgr.getLineNumber(Range.getEnd())) {
  auto StartLineAndColumn = SourceMgr.getLineAndColumn(Range.getStart());
  StartLine = StartLineAndColumn.first;
  StartColumn = StartLineAndColumn.second;
}

SingleRawComment::SingleRawComment(StringRef RawText, unsigned StartColumn)
    : RawText(RawText), Kind(static_cast<unsigned>(getCommentKind(RawText))),
      StartColumn(StartColumn), StartLine(0), EndLine(0) {}

static bool canHaveComment(const Decl *D) {
  return !D->hasClangNode() &&
         (isa<ValueDecl>(D) || isa<ExtensionDecl>(D)) &&
         !isa<ParamDecl>(D) &&
         (!isa<AbstractTypeParamDecl>(D) || isa<AssociatedTypeDecl>(D));
}

static void addCommentToList(SmallVectorImpl<SingleRawComment> &Comments,
                             const SingleRawComment &SRC) {
  // TODO: consider producing warnings when we decide not to merge comments.

  if (SRC.isOrdinary()) {
    // Skip gyb comments that are line number markers.
    if (SRC.RawText.startswith("// ###"))
      return;

    Comments.clear();
    return;
  }

  // If this is the first documentation comment, save it (because there isn't
  // anything to merge it with).
  if (Comments.empty()) {
    Comments.push_back(SRC);
    return;
  }

  auto &Last = Comments.back();

  // Merge comments if they are on same or consecutive lines.
  if (Last.EndLine + 1 < SRC.StartLine) {
    Comments.clear();
    return;
  }

  Comments.push_back(SRC);
}

static RawComment toRawComment(ASTContext &Context, CharSourceRange Range) {
  if (Range.isInvalid())
    return RawComment();

  auto &SourceMgr = Context.SourceMgr;
  unsigned BufferID = SourceMgr.findBufferContainingLoc(Range.getStart());
  unsigned Offset = SourceMgr.getLocOffsetInBuffer(Range.getStart(), BufferID);
  unsigned EndOffset = SourceMgr.getLocOffsetInBuffer(Range.getEnd(), BufferID);
  LangOptions FakeLangOpts;
  Lexer L(FakeLangOpts, SourceMgr, BufferID, nullptr, /*InSILMode=*/false,
          CommentRetentionMode::ReturnAsTokens, Offset, EndOffset);
  SmallVector<SingleRawComment, 16> Comments;
  Token Tok;
  while (true) {
    L.lex(Tok);
    if (Tok.is(tok::eof))
      break;
    assert(Tok.is(tok::comment));
    addCommentToList(Comments, SingleRawComment(Tok.getRange(), SourceMgr));
  }
  RawComment Result;
  Result.Comments = Context.AllocateCopy(Comments);
  return Result;
}

RawComment Decl::getRawComment() const {
  if (!canHaveComment(this))
    return RawComment();

  // Check the cache in ASTContext.
  auto &Context = getASTContext();
  if (Optional<RawComment> RC = Context.getRawComment(this))
    return RC.getValue();

  // Check the declaration itself.
  if (auto *Attr = getAttrs().getAttribute<RawDocCommentAttr>()) {
    RawComment Result = toRawComment(Context, Attr->getCommentRange());
    Context.setRawComment(this, Result);
    return Result;
  }

  // Ask the parent module.
  if (auto *Unit =
          dyn_cast<FileUnit>(this->getDeclContext()->getModuleScopeContext())) {
    if (Optional<CommentInfo> C = Unit->getCommentForDecl(this)) {
      llvm::markup::MarkupContext MC;
      Context.setBriefComment(this, C->Brief);
      Context.setRawComment(this, C->Raw);
      return C->Raw;
    }
  }

  // Give up.
  return RawComment();
}

Optional<StringRef> Decl::getGroupName() const {

  // We can only get group information from deserialized module files.
  if (auto *Unit =
      dyn_cast<FileUnit>(this->getDeclContext()->getModuleScopeContext())) {
    return Unit->getGroupNameForDecl(this);
  }
  return None;
}

Optional<StringRef> Decl::getSourceFileName() const {

  // We can only get group information from deserialized module files.
  if (auto *Unit =
      dyn_cast<FileUnit>(this->getDeclContext()->getModuleScopeContext())) {
    return Unit->getSourceFileNameForDecl(this);
  }
  return None;
}

Optional<unsigned> Decl::getSourceOrder() const {

  // We can only get source orders from deserialized module files.
  if (auto *Unit =
      dyn_cast<FileUnit>(this->getDeclContext()->getModuleScopeContext())) {
    return  Unit->getSourceOrderForDecl(this);
  }
  return None;
}

static StringRef extractBriefComment(ASTContext &Context, RawComment RC,
                                     const Decl *D) {
  PrettyStackTraceDecl StackTrace("extracting brief comment for", D);

  if (!canHaveComment(D))
    return StringRef();

  llvm::markup::MarkupContext MC;
  auto DC = getDocComment(MC, D);
  if (!DC.hasValue())
    return StringRef();

  auto Brief = DC.getValue()->getBrief();
  if (!Brief.hasValue())
    return StringRef();

  SmallString<256> BriefStr("");
  llvm::raw_svector_ostream OS(BriefStr);
  llvm::markup::printInlinesUnder(Brief.getValue(), OS);
  if (OS.str().empty())
    return StringRef();

  return Context.AllocateCopy(OS.str());
}

StringRef Decl::getBriefComment() const {
  if (!canHaveComment(this))
    return StringRef();

  auto &Context = getASTContext();
  if (Optional<StringRef> Comment = Context.getBriefComment(this))
    return Comment.getValue();

  StringRef Result;
  auto RC = getRawComment();
  if (!RC.isEmpty())
    Result = extractBriefComment(Context, RC, this);

  Context.setBriefComment(this, Result);
  return Result;
}
<commit_msg>[gardening] Fix recently introduced accidental double space<commit_after>//===--- RawComment.cpp - Extraction of raw comments ----------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file implements extraction of raw comments.
///
//===----------------------------------------------------------------------===//

#include "swift/AST/RawComment.h"
#include "swift/AST/Comment.h"
#include "swift/AST/ASTContext.h"
#include "swift/AST/Decl.h"
#include "swift/AST/Module.h"
#include "swift/AST/PrettyStackTrace.h"
#include "swift/Basic/PrimitiveParsing.h"
#include "swift/Basic/SourceManager.h"
#include "swift/Markup/Markup.h"
#include "swift/Parse/Lexer.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/raw_ostream.h"

using namespace swift;

static SingleRawComment::CommentKind getCommentKind(StringRef Comment) {
  assert(Comment.size() >= 2);
  assert(Comment[0] == '/');

  if (Comment[1] == '/') {
    if (Comment.size() < 3)
      return SingleRawComment::CommentKind::OrdinaryLine;

    if (Comment[2] == '/') {
      return SingleRawComment::CommentKind::LineDoc;
    }
    return SingleRawComment::CommentKind::OrdinaryLine;
  } else {
    assert(Comment[1] == '*');
    assert(Comment.size() >= 4);
    if (Comment[2] == '*') {
      return SingleRawComment::CommentKind::BlockDoc;
    }
    return SingleRawComment::CommentKind::OrdinaryBlock;
  }
}

SingleRawComment::SingleRawComment(CharSourceRange Range,
                                   const SourceManager &SourceMgr)
    : Range(Range), RawText(SourceMgr.extractText(Range)),
      Kind(static_cast<unsigned>(getCommentKind(RawText))),
      EndLine(SourceMgr.getLineNumber(Range.getEnd())) {
  auto StartLineAndColumn = SourceMgr.getLineAndColumn(Range.getStart());
  StartLine = StartLineAndColumn.first;
  StartColumn = StartLineAndColumn.second;
}

SingleRawComment::SingleRawComment(StringRef RawText, unsigned StartColumn)
    : RawText(RawText), Kind(static_cast<unsigned>(getCommentKind(RawText))),
      StartColumn(StartColumn), StartLine(0), EndLine(0) {}

static bool canHaveComment(const Decl *D) {
  return !D->hasClangNode() &&
         (isa<ValueDecl>(D) || isa<ExtensionDecl>(D)) &&
         !isa<ParamDecl>(D) &&
         (!isa<AbstractTypeParamDecl>(D) || isa<AssociatedTypeDecl>(D));
}

static void addCommentToList(SmallVectorImpl<SingleRawComment> &Comments,
                             const SingleRawComment &SRC) {
  // TODO: consider producing warnings when we decide not to merge comments.

  if (SRC.isOrdinary()) {
    // Skip gyb comments that are line number markers.
    if (SRC.RawText.startswith("// ###"))
      return;

    Comments.clear();
    return;
  }

  // If this is the first documentation comment, save it (because there isn't
  // anything to merge it with).
  if (Comments.empty()) {
    Comments.push_back(SRC);
    return;
  }

  auto &Last = Comments.back();

  // Merge comments if they are on same or consecutive lines.
  if (Last.EndLine + 1 < SRC.StartLine) {
    Comments.clear();
    return;
  }

  Comments.push_back(SRC);
}

static RawComment toRawComment(ASTContext &Context, CharSourceRange Range) {
  if (Range.isInvalid())
    return RawComment();

  auto &SourceMgr = Context.SourceMgr;
  unsigned BufferID = SourceMgr.findBufferContainingLoc(Range.getStart());
  unsigned Offset = SourceMgr.getLocOffsetInBuffer(Range.getStart(), BufferID);
  unsigned EndOffset = SourceMgr.getLocOffsetInBuffer(Range.getEnd(), BufferID);
  LangOptions FakeLangOpts;
  Lexer L(FakeLangOpts, SourceMgr, BufferID, nullptr, /*InSILMode=*/false,
          CommentRetentionMode::ReturnAsTokens, Offset, EndOffset);
  SmallVector<SingleRawComment, 16> Comments;
  Token Tok;
  while (true) {
    L.lex(Tok);
    if (Tok.is(tok::eof))
      break;
    assert(Tok.is(tok::comment));
    addCommentToList(Comments, SingleRawComment(Tok.getRange(), SourceMgr));
  }
  RawComment Result;
  Result.Comments = Context.AllocateCopy(Comments);
  return Result;
}

RawComment Decl::getRawComment() const {
  if (!canHaveComment(this))
    return RawComment();

  // Check the cache in ASTContext.
  auto &Context = getASTContext();
  if (Optional<RawComment> RC = Context.getRawComment(this))
    return RC.getValue();

  // Check the declaration itself.
  if (auto *Attr = getAttrs().getAttribute<RawDocCommentAttr>()) {
    RawComment Result = toRawComment(Context, Attr->getCommentRange());
    Context.setRawComment(this, Result);
    return Result;
  }

  // Ask the parent module.
  if (auto *Unit =
          dyn_cast<FileUnit>(this->getDeclContext()->getModuleScopeContext())) {
    if (Optional<CommentInfo> C = Unit->getCommentForDecl(this)) {
      llvm::markup::MarkupContext MC;
      Context.setBriefComment(this, C->Brief);
      Context.setRawComment(this, C->Raw);
      return C->Raw;
    }
  }

  // Give up.
  return RawComment();
}

Optional<StringRef> Decl::getGroupName() const {

  // We can only get group information from deserialized module files.
  if (auto *Unit =
      dyn_cast<FileUnit>(this->getDeclContext()->getModuleScopeContext())) {
    return Unit->getGroupNameForDecl(this);
  }
  return None;
}

Optional<StringRef> Decl::getSourceFileName() const {

  // We can only get group information from deserialized module files.
  if (auto *Unit =
      dyn_cast<FileUnit>(this->getDeclContext()->getModuleScopeContext())) {
    return Unit->getSourceFileNameForDecl(this);
  }
  return None;
}

Optional<unsigned> Decl::getSourceOrder() const {

  // We can only get source orders from deserialized module files.
  if (auto *Unit =
      dyn_cast<FileUnit>(this->getDeclContext()->getModuleScopeContext())) {
    return Unit->getSourceOrderForDecl(this);
  }
  return None;
}

static StringRef extractBriefComment(ASTContext &Context, RawComment RC,
                                     const Decl *D) {
  PrettyStackTraceDecl StackTrace("extracting brief comment for", D);

  if (!canHaveComment(D))
    return StringRef();

  llvm::markup::MarkupContext MC;
  auto DC = getDocComment(MC, D);
  if (!DC.hasValue())
    return StringRef();

  auto Brief = DC.getValue()->getBrief();
  if (!Brief.hasValue())
    return StringRef();

  SmallString<256> BriefStr("");
  llvm::raw_svector_ostream OS(BriefStr);
  llvm::markup::printInlinesUnder(Brief.getValue(), OS);
  if (OS.str().empty())
    return StringRef();

  return Context.AllocateCopy(OS.str());
}

StringRef Decl::getBriefComment() const {
  if (!canHaveComment(this))
    return StringRef();

  auto &Context = getASTContext();
  if (Optional<StringRef> Comment = Context.getBriefComment(this))
    return Comment.getValue();

  StringRef Result;
  auto RC = getRawComment();
  if (!RC.isEmpty())
    Result = extractBriefComment(Context, RC, this);

  Context.setBriefComment(this, Result);
  return Result;
}
<|endoftext|>