<commit_before>/*************************************************************************
 *
 *  $RCSfile: VPolarAxis.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: bm $ $Date: 2004-01-26 09:13:12 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2003 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#include "VPolarAxis.hxx"
#include "VPolarGrid.hxx"
#include "VCartesianAxis.hxx"
#include "PlottingPositionHelper.hxx"
#include "ShapeFactory.hxx"
#include "CommonConverters.hxx"
#include "macros.hxx"
#include "ViewDefines.hxx"
#include "TickmarkHelper.hxx"
#include "PropertyMapper.hxx"
#include "chartview/NumberFormatterWrapper.hxx"
#include "chartview/ObjectIdentifier.hxx"
#include "PolarLabelPositionHelper.hxx"

#ifndef INCLUDED_RTL_MATH_HXX
#include <rtl/math.hxx>
#endif
#ifndef _TOOLS_COLOR_HXX
#include <tools/color.hxx>
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef _COM_SUN_STAR_STYLE_PARAGRAPHADJUST_HPP_
#include <com/sun/star/style/ParagraphAdjust.hpp>
#endif
#ifndef _COM_SUN_STAR_TEXT_XTEXT_HPP_
#include <com/sun/star/text/XText.hpp>
#endif
#ifndef _COM_SUN_STAR_CHART2_XIDENTIFIABLE_HPP_
#include <com/sun/star/chart2/XIdentifiable.hpp>
#endif

#ifndef _SVX_UNOPRNMS_HXX
#include <svx/unoprnms.hxx>
#endif

#include <algorithm>
#include <memory>

//.............................................................................
namespace chart
{
//.............................................................................
using namespace ::com::sun::star;
using namespace ::com::sun::star::chart2;
using namespace ::rtl::math;

VPolarAxis::VPolarAxis( const AxisProperties& rAxisProperties
            , NumberFormatterWrapper* pNumberFormatterWrapper
            , sal_Int32 nDimensionCount )
            : VMeterBase( uno::Reference<XMeter>::query(rAxisProperties.m_xAxisModel)
                , nDimensionCount )
            , m_aAxisProperties( rAxisProperties )
            , m_pNumberFormatterWrapper( pNumberFormatterWrapper )
            , m_pPosHelper( new PolarPlottingPositionHelper(false) )
            , m_aIncrements()
{
    PlotterBase::m_pPosHelper = m_pPosHelper;
}

VPolarAxis::~VPolarAxis()
{
    delete m_pPosHelper;
    m_pPosHelper = NULL;
}

void VPolarAxis::setIncrements( const uno::Sequence< ExplicitIncrementData >& rIncrements )
{
    m_aIncrements = rIncrements;
}

bool createTextShapes_ForAngleAxis( const uno::Reference< lang::XMultiServiceFactory >& xShapeFactory
                     , const uno::Reference< drawing::XShapes >& xTarget
                     , ::std::vector< ::std::vector< TickInfo > >& rAllTickInfos
                     , const ExplicitIncrementData& rIncrement
                     , AxisLabelProperties& rAxisLabelProperties
                     , const AxisProperties& rAxisProperties
                     , PolarPlottingPositionHelper* pPosHelper
                     , double fLogicRadius
                     , double fLogicZ
                     , const FixedNumberFormatter& rFixedNumberFormatter )
{
    sal_Int32 nDimensionCount = 2;
    ShapeFactory aShapeFactory(xShapeFactory);

    //------------------------------------------------
    //prepare text properties for multipropertyset-interface of shape
    tNameSequence aPropNames;
    tAnySequence aPropValues;

    uno::Reference< beans::XPropertySet > xProps( rAxisProperties.m_xAxisModel, uno::UNO_QUERY );
    PropertyMapper::getTextLabelMultiPropertyLists( xProps, aPropNames, aPropValues, false );
    LabelPositionHelper::doDynamicFontResize( aPropValues, aPropNames, xProps
        , rAxisProperties.m_aReferenceSize );

    uno::Any* pColorAny = PropertyMapper::getValuePointer(aPropValues,aPropNames,C2U("CharColor"));
    sal_Int32 nColor = Color( COL_AUTO ).GetColor();
    if(pColorAny)
        *pColorAny >>= nColor;
    //------------------------------------------------

    //TickInfo* pLastVisibleNeighbourTickInfo = NULL;
    sal_Int32 nTick = 0;
    TickIter aIter( rAllTickInfos, rIncrement, 0, 0 );
    for( TickInfo* pTickInfo = aIter.firstInfo()
        ; pTickInfo
        ; pTickInfo = aIter.nextInfo(), nTick++ )
    {
        //don't create labels which does not fit into the rythm
        if( nTick%rAxisLabelProperties.nRhythm != 0)
            continue;

        //don't create labels for invisible ticks
        if( !pTickInfo->bPaintIt )
            continue;

        //if NO OVERLAP -> don't create labels where the
        //anchor position is the same as for the last label
        //@todo

        if(!pTickInfo->xTextShape.is())
        {
            //create single label
            bool bHasExtraColor=false;
            sal_Int32 nExtraColor=0;
            rtl::OUString aLabel = rFixedNumberFormatter.getFormattedString( pTickInfo->fUnscaledTickValue, nExtraColor, bHasExtraColor );
            if(pColorAny)
                *pColorAny = uno::makeAny(bHasExtraColor?nExtraColor:nColor);

            double fLogicAngle = pTickInfo->fUnscaledTickValue;

            LabelAlignment eLabelAlignment(LABEL_ALIGN_CENTER);
            PolarLabelPositionHelper aPolarLabelPositionHelper(pPosHelper,nDimensionCount,xTarget,&aShapeFactory);
            awt::Point aAnchorScreenPosition2D( aPolarLabelPositionHelper.getLabelScreenPositionAndAlignment(
                    eLabelAlignment, true, fLogicAngle, fLogicAngle, fLogicRadius, fLogicRadius, fLogicZ ));
            LabelPositionHelper::changeTextAdjustment( aPropValues, aPropNames, eLabelAlignment );

            double fRotationAnglePi = rAxisLabelProperties.fRotationAngleDegree*F_PI/180.0;
            uno::Any aATransformation = ShapeFactory::makeTransformation( aAnchorScreenPosition2D, fRotationAnglePi );
            rtl::OUString aStackedLabel = ShapeFactory::getStackedString( aLabel, rAxisLabelProperties.bStackCharacters );

            pTickInfo->xTextShape = aShapeFactory.createText( xTarget, aStackedLabel, aPropNames, aPropValues, aATransformation );
        }

        //if NO OVERLAP -> remove overlapping shapes
        //@todo
    }
    return true;
}

void VPolarAxis::create2DAngleAxis( const uno::Reference< drawing::XShapes >& xTarget, ::std::vector< ::std::vector< TickInfo > >& rAllTickInfos )
{
    double fLogicRadius = m_pPosHelper->getOuterLogicRadius();
    double fLogicZ      = -0.5;//as defined

    //-----------------------------------------
    //create axis main lines
    drawing::PointSequenceSequence aPoints(1);
    VPolarGrid::createLinePointSequence_ForAngleAxis( aPoints, rAllTickInfos, m_aIncrement, m_aScale, m_pPosHelper, fLogicRadius, fLogicZ );
    uno::Reference< drawing::XShape > xShape = m_pShapeFactory->createLine2D(
            xTarget, aPoints, m_aAxisProperties.m_aLineProperties );
    //because of this name this line will be used for marking the axis
    m_pShapeFactory->setShapeName( xShape, C2U("MarkHandles") );

    //-----------------------------------------
    //create labels
    if( m_aAxisProperties.m_bDisplayLabels )
    {
        AxisLabelProperties aAxisLabelProperties;
        aAxisLabelProperties.init(m_aAxisProperties.m_xAxisModel);

        FixedNumberFormatter aFixedNumberFormatter(
                m_pNumberFormatterWrapper, aAxisLabelProperties.aNumberFormat );

        while( !createTextShapes_ForAngleAxis( m_xShapeFactory, xTarget, rAllTickInfos
                        , m_aIncrement, aAxisLabelProperties, m_aAxisProperties, m_pPosHelper
                        , fLogicRadius, fLogicZ
                        , aFixedNumberFormatter
                        ) )
        {
        };

        //no staggering for polar angle axis
    }
}

void VPolarAxis::create2DRadiusAxis( const uno::Reference< drawing::XShapes >& xTarget, ::std::vector< ::std::vector< TickInfo > >& rAllTickInfos )
{
    const ExplicitScaleData& rAngleScale         = m_pPosHelper->getScales()[0];
    const ExplicitIncrementData& rAngleIncrement = m_aIncrements[0];

    ::std::vector< ::std::vector< TickInfo > > aAngleTickInfos;
    TickmarkHelper aAngleTickmarkHelper( rAngleScale, rAngleIncrement );
    aAngleTickmarkHelper.getAllTicks( aAngleTickInfos );

    uno::Reference< XScaling > xInverseScaling( NULL );
    if( rAngleScale.Scaling.is() )
        xInverseScaling = rAngleScale.Scaling->getInverseScaling();

    AxisProperties aAxisProperties(m_aAxisProperties);
    aAxisProperties.m_fInnerDirectionSign=0.0;
    aAxisProperties.m_bLabelsOutside=true;
    aAxisProperties.m_bIsMainAxis=false;
    aAxisProperties.m_aLabelAlignment=LABEL_ALIGN_RIGHT;
    aAxisProperties.init();

    sal_Int32 nTick = 0;
    TickIter aIter( aAngleTickInfos, rAngleIncrement, 0, 0 );
    for( TickInfo* pTickInfo = aIter.firstInfo()
        ; pTickInfo; pTickInfo = aIter.nextInfo(), nTick++ )
    {
        pTickInfo->updateUnscaledValue( xInverseScaling );
        aAxisProperties.m_pfMainLinePositionAtOtherAxis = new double( pTickInfo->fUnscaledTickValue );
        if(nTick)
            aAxisProperties.m_bDisplayLabels=false;

        //-------------------
        VCartesianAxis aAxis(aAxisProperties,m_pNumberFormatterWrapper
            ,2,new PolarPlottingPositionHelper(false));
        aAxis.setMeterData( m_aScale, m_aIncrement );
        aAxis.init(m_xLogicTarget,m_xFinalTarget,m_xShapeFactory);
        aAxis.setTransformationSceneToScreen( Matrix4DToHomogenMatrix( m_aMatrixScreenToScene ) );
        aAxis.setScales( m_pPosHelper->getScales() );
        aAxis.createShapes();
    }
}

void SAL_CALL VPolarAxis::createShapes()
{
    DBG_ASSERT(m_pShapeFactory&&m_xLogicTarget.is()&&m_xFinalTarget.is(),"Axis is not proper initialized");
    if(!(m_pShapeFactory&&m_xLogicTarget.is()&&m_xFinalTarget.is()))
        return;

    //-----------------------------------------
    //create named group shape
    uno::Reference< XIdentifiable > xIdent( m_aAxisProperties.m_xAxisModel, uno::UNO_QUERY );
    DBG_ASSERT( xIdent.is(), "Axis should support XIdentifiable" );
    if( ! xIdent.is())
        return;
    uno::Reference< drawing::XShapes > xGroupShape_Shapes(
        m_pShapeFactory->createGroup2D( m_xLogicTarget
        , ObjectIdentifier::createClassifiedIdentifier(
                OBJECTTYPE_AXIS, xIdent->getIdentifier() )
        ) );

    //-----------------------------------------
    //create all scaled tickmark values
    std::auto_ptr< TickmarkHelper > apTickmarkHelper( this->createTickmarkHelper() );
    ::std::vector< ::std::vector< TickInfo > > aAllTickInfos;
    apTickmarkHelper->getAllTicks( aAllTickInfos );

    //-----------------------------------------
    //create different axes
    if(2==m_nDimension)
    {
        sal_Int32 nDimensionIndex = m_xMeter->getRepresentedDimension();
        if(nDimensionIndex==0)
            this->create2DAngleAxis( xGroupShape_Shapes, aAllTickInfos );
        else if(nDimensionIndex==1)
            this->create2DRadiusAxis( xGroupShape_Shapes, aAllTickInfos );

    }
}

//.............................................................................
} //namespace chart
//.............................................................................
<commit_msg>INTEGRATION: CWS ooo19126 (1.5.110); FILE MERGED 2005/09/05 18:43:41 rt 1.5.110.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: VPolarAxis.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 01:40:05 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#include "VPolarAxis.hxx"
#include "VPolarGrid.hxx"
#include "VCartesianAxis.hxx"
#include "PlottingPositionHelper.hxx"
#include "ShapeFactory.hxx"
#include "CommonConverters.hxx"
#include "macros.hxx"
#include "ViewDefines.hxx"
#include "TickmarkHelper.hxx"
#include "PropertyMapper.hxx"
#include "chartview/NumberFormatterWrapper.hxx"
#include "chartview/ObjectIdentifier.hxx"
#include "PolarLabelPositionHelper.hxx"

#ifndef INCLUDED_RTL_MATH_HXX
#include <rtl/math.hxx>
#endif
#ifndef _TOOLS_COLOR_HXX
#include <tools/color.hxx>
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef _COM_SUN_STAR_STYLE_PARAGRAPHADJUST_HPP_
#include <com/sun/star/style/ParagraphAdjust.hpp>
#endif
#ifndef _COM_SUN_STAR_TEXT_XTEXT_HPP_
#include <com/sun/star/text/XText.hpp>
#endif
#ifndef _COM_SUN_STAR_CHART2_XIDENTIFIABLE_HPP_
#include <com/sun/star/chart2/XIdentifiable.hpp>
#endif

#ifndef _SVX_UNOPRNMS_HXX
#include <svx/unoprnms.hxx>
#endif

#include <algorithm>
#include <memory>

//.............................................................................
namespace chart
{
//.............................................................................
using namespace ::com::sun::star;
using namespace ::com::sun::star::chart2;
using namespace ::rtl::math;

VPolarAxis::VPolarAxis( const AxisProperties& rAxisProperties
            , NumberFormatterWrapper* pNumberFormatterWrapper
            , sal_Int32 nDimensionCount )
            : VMeterBase( uno::Reference<XMeter>::query(rAxisProperties.m_xAxisModel)
                , nDimensionCount )
            , m_aAxisProperties( rAxisProperties )
            , m_pNumberFormatterWrapper( pNumberFormatterWrapper )
            , m_pPosHelper( new PolarPlottingPositionHelper(false) )
            , m_aIncrements()
{
    PlotterBase::m_pPosHelper = m_pPosHelper;
}

VPolarAxis::~VPolarAxis()
{
    delete m_pPosHelper;
    m_pPosHelper = NULL;
}

void VPolarAxis::setIncrements( const uno::Sequence< ExplicitIncrementData >& rIncrements )
{
    m_aIncrements = rIncrements;
}

bool createTextShapes_ForAngleAxis( const uno::Reference< lang::XMultiServiceFactory >& xShapeFactory
                     , const uno::Reference< drawing::XShapes >& xTarget
                     , ::std::vector< ::std::vector< TickInfo > >& rAllTickInfos
                     , const ExplicitIncrementData& rIncrement
                     , AxisLabelProperties& rAxisLabelProperties
                     , const AxisProperties& rAxisProperties
                     , PolarPlottingPositionHelper* pPosHelper
                     , double fLogicRadius
                     , double fLogicZ
                     , const FixedNumberFormatter& rFixedNumberFormatter )
{
    sal_Int32 nDimensionCount = 2;
    ShapeFactory aShapeFactory(xShapeFactory);

    //------------------------------------------------
    //prepare text properties for multipropertyset-interface of shape
    tNameSequence aPropNames;
    tAnySequence aPropValues;

    uno::Reference< beans::XPropertySet > xProps( rAxisProperties.m_xAxisModel, uno::UNO_QUERY );
    PropertyMapper::getTextLabelMultiPropertyLists( xProps, aPropNames, aPropValues, false );
    LabelPositionHelper::doDynamicFontResize( aPropValues, aPropNames, xProps
        , rAxisProperties.m_aReferenceSize );

    uno::Any* pColorAny = PropertyMapper::getValuePointer(aPropValues,aPropNames,C2U("CharColor"));
    sal_Int32 nColor = Color( COL_AUTO ).GetColor();
    if(pColorAny)
        *pColorAny >>= nColor;
    //------------------------------------------------

    //TickInfo* pLastVisibleNeighbourTickInfo = NULL;
    sal_Int32 nTick = 0;
    TickIter aIter( rAllTickInfos, rIncrement, 0, 0 );
    for( TickInfo* pTickInfo = aIter.firstInfo()
        ; pTickInfo
        ; pTickInfo = aIter.nextInfo(), nTick++ )
    {
        //don't create labels which does not fit into the rythm
        if( nTick%rAxisLabelProperties.nRhythm != 0)
            continue;

        //don't create labels for invisible ticks
        if( !pTickInfo->bPaintIt )
            continue;

        //if NO OVERLAP -> don't create labels where the
        //anchor position is the same as for the last label
        //@todo

        if(!pTickInfo->xTextShape.is())
        {
            //create single label
            bool bHasExtraColor=false;
            sal_Int32 nExtraColor=0;
            rtl::OUString aLabel = rFixedNumberFormatter.getFormattedString( pTickInfo->fUnscaledTickValue, nExtraColor, bHasExtraColor );
            if(pColorAny)
                *pColorAny = uno::makeAny(bHasExtraColor?nExtraColor:nColor);

            double fLogicAngle = pTickInfo->fUnscaledTickValue;

            LabelAlignment eLabelAlignment(LABEL_ALIGN_CENTER);
            PolarLabelPositionHelper aPolarLabelPositionHelper(pPosHelper,nDimensionCount,xTarget,&aShapeFactory);
            awt::Point aAnchorScreenPosition2D( aPolarLabelPositionHelper.getLabelScreenPositionAndAlignment(
                    eLabelAlignment, true, fLogicAngle, fLogicAngle, fLogicRadius, fLogicRadius, fLogicZ ));
            LabelPositionHelper::changeTextAdjustment( aPropValues, aPropNames, eLabelAlignment );

            double fRotationAnglePi = rAxisLabelProperties.fRotationAngleDegree*F_PI/180.0;
            uno::Any aATransformation = ShapeFactory::makeTransformation( aAnchorScreenPosition2D, fRotationAnglePi );
            rtl::OUString aStackedLabel = ShapeFactory::getStackedString( aLabel, rAxisLabelProperties.bStackCharacters );

            pTickInfo->xTextShape = aShapeFactory.createText( xTarget, aStackedLabel, aPropNames, aPropValues, aATransformation );
        }

        //if NO OVERLAP -> remove overlapping shapes
        //@todo
    }
    return true;
}

void VPolarAxis::create2DAngleAxis( const uno::Reference< drawing::XShapes >& xTarget, ::std::vector< ::std::vector< TickInfo > >& rAllTickInfos )
{
    double fLogicRadius = m_pPosHelper->getOuterLogicRadius();
    double fLogicZ      = -0.5;//as defined

    //-----------------------------------------
    //create axis main lines
    drawing::PointSequenceSequence aPoints(1);
    VPolarGrid::createLinePointSequence_ForAngleAxis( aPoints, rAllTickInfos, m_aIncrement, m_aScale, m_pPosHelper, fLogicRadius, fLogicZ );
    uno::Reference< drawing::XShape > xShape = m_pShapeFactory->createLine2D(
            xTarget, aPoints, m_aAxisProperties.m_aLineProperties );
    //because of this name this line will be used for marking the axis
    m_pShapeFactory->setShapeName( xShape, C2U("MarkHandles") );

    //-----------------------------------------
    //create labels
    if( m_aAxisProperties.m_bDisplayLabels )
    {
        AxisLabelProperties aAxisLabelProperties;
        aAxisLabelProperties.init(m_aAxisProperties.m_xAxisModel);

        FixedNumberFormatter aFixedNumberFormatter(
                m_pNumberFormatterWrapper, aAxisLabelProperties.aNumberFormat );

        while( !createTextShapes_ForAngleAxis( m_xShapeFactory, xTarget, rAllTickInfos
                        , m_aIncrement, aAxisLabelProperties, m_aAxisProperties, m_pPosHelper
                        , fLogicRadius, fLogicZ
                        , aFixedNumberFormatter
                        ) )
        {
        };

        //no staggering for polar angle axis
    }
}

void VPolarAxis::create2DRadiusAxis( const uno::Reference< drawing::XShapes >& xTarget, ::std::vector< ::std::vector< TickInfo > >& rAllTickInfos )
{
    const ExplicitScaleData& rAngleScale         = m_pPosHelper->getScales()[0];
    const ExplicitIncrementData& rAngleIncrement = m_aIncrements[0];

    ::std::vector< ::std::vector< TickInfo > > aAngleTickInfos;
    TickmarkHelper aAngleTickmarkHelper( rAngleScale, rAngleIncrement );
    aAngleTickmarkHelper.getAllTicks( aAngleTickInfos );

    uno::Reference< XScaling > xInverseScaling( NULL );
    if( rAngleScale.Scaling.is() )
        xInverseScaling = rAngleScale.Scaling->getInverseScaling();

    AxisProperties aAxisProperties(m_aAxisProperties);
    aAxisProperties.m_fInnerDirectionSign=0.0;
    aAxisProperties.m_bLabelsOutside=true;
    aAxisProperties.m_bIsMainAxis=false;
    aAxisProperties.m_aLabelAlignment=LABEL_ALIGN_RIGHT;
    aAxisProperties.init();

    sal_Int32 nTick = 0;
    TickIter aIter( aAngleTickInfos, rAngleIncrement, 0, 0 );
    for( TickInfo* pTickInfo = aIter.firstInfo()
        ; pTickInfo; pTickInfo = aIter.nextInfo(), nTick++ )
    {
        pTickInfo->updateUnscaledValue( xInverseScaling );
        aAxisProperties.m_pfMainLinePositionAtOtherAxis = new double( pTickInfo->fUnscaledTickValue );
        if(nTick)
            aAxisProperties.m_bDisplayLabels=false;

        //-------------------
        VCartesianAxis aAxis(aAxisProperties,m_pNumberFormatterWrapper
            ,2,new PolarPlottingPositionHelper(false));
        aAxis.setMeterData( m_aScale, m_aIncrement );
        aAxis.init(m_xLogicTarget,m_xFinalTarget,m_xShapeFactory);
        aAxis.setTransformationSceneToScreen( Matrix4DToHomogenMatrix( m_aMatrixScreenToScene ) );
        aAxis.setScales( m_pPosHelper->getScales() );
        aAxis.createShapes();
    }
}

void SAL_CALL VPolarAxis::createShapes()
{
    DBG_ASSERT(m_pShapeFactory&&m_xLogicTarget.is()&&m_xFinalTarget.is(),"Axis is not proper initialized");
    if(!(m_pShapeFactory&&m_xLogicTarget.is()&&m_xFinalTarget.is()))
        return;

    //-----------------------------------------
    //create named group shape
    uno::Reference< XIdentifiable > xIdent( m_aAxisProperties.m_xAxisModel, uno::UNO_QUERY );
    DBG_ASSERT( xIdent.is(), "Axis should support XIdentifiable" );
    if( ! xIdent.is())
        return;
    uno::Reference< drawing::XShapes > xGroupShape_Shapes(
        m_pShapeFactory->createGroup2D( m_xLogicTarget
        , ObjectIdentifier::createClassifiedIdentifier(
                OBJECTTYPE_AXIS, xIdent->getIdentifier() )
        ) );

    //-----------------------------------------
    //create all scaled tickmark values
    std::auto_ptr< TickmarkHelper > apTickmarkHelper( this->createTickmarkHelper() );
    ::std::vector< ::std::vector< TickInfo > > aAllTickInfos;
    apTickmarkHelper->getAllTicks( aAllTickInfos );

    //-----------------------------------------
    //create different axes
    if(2==m_nDimension)
    {
        sal_Int32 nDimensionIndex = m_xMeter->getRepresentedDimension();
        if(nDimensionIndex==0)
            this->create2DAngleAxis( xGroupShape_Shapes, aAllTickInfos );
        else if(nDimensionIndex==1)
            this->create2DRadiusAxis( xGroupShape_Shapes, aAllTickInfos );

    }
}

//.............................................................................
} //namespace chart
//.............................................................................
<|endoftext|>


<commit_before>/*
 * Copyright 2015 WebAssembly Community Group participants
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

//
// A WebAssembly shell, loads a .wast file (WebAssembly in S-Expression format)
// and executes it. This provides similar functionality as the reference
// interpreter, like assert_* calls, so it can run the spec test suite.
//

#include <setjmp.h>
#include <memory>

#include "wasm-s-parser.h"
#include "wasm-interpreter.h"
#include "wasm-validator.h"
#include "pass.h"

using namespace cashew;
using namespace wasm;

namespace wasm {
int debug = 0;
}

// Globals

MixedArena globalAllocator;

IString ASSERT_RETURN("assert_return"),
        ASSERT_TRAP("assert_trap"),
        ASSERT_INVALID("assert_invalid"),
        SPECTEST("spectest"),
        PRINT("print"),
        INVOKE("invoke");

//
// Implementation of the shell interpreter execution environment
//

struct ShellExternalInterface : ModuleInstance::ExternalInterface {
  char *memory;

  ShellExternalInterface() : memory(nullptr) {}

  void init(Module& wasm) override {
    memory = (char*)calloc(wasm.memory.initial, 1);
    // apply memory segments
    for (auto segment : wasm.memory.segments) {
      memcpy(memory + segment.offset, segment.data, segment.size);
    }
  }

  Literal callImport(Import *import, ModuleInstance::LiteralList& arguments) override {
    if (import->module == SPECTEST && import->base == PRINT) {
      for (auto argument : arguments) {
        std::cout << argument << '\n';
      }
      return Literal();
    }
    std::cout << "callImport " << import->name.str << "\n";
    abort();
  }

  Literal load(Load* load, size_t addr) override {
    // ignore align - assume we are on x86 etc. which does that
    switch (load->type) {
      case i32: {
        switch (load->bytes) {
          case 1: return load->signed_ ? (int32_t)*((int8_t*)(memory+addr))  : (int32_t)*((uint8_t*)(memory+addr));
          case 2: return load->signed_ ? (int32_t)*((int16_t*)(memory+addr)) : (int32_t)*((uint16_t*)(memory+addr));
          case 4: return load->signed_ ? (int32_t)*((int32_t*)(memory+addr)) : (int32_t)*((uint32_t*)(memory+addr));
          default: abort();
        }
        break;
      }
      case i64: {
        switch (load->bytes) {
          case 1: return load->signed_ ? (int64_t)*((int8_t*)(memory+addr))  : (int64_t)*((uint8_t*)(memory+addr));
          case 2: return load->signed_ ? (int64_t)*((int16_t*)(memory+addr)) : (int64_t)*((uint16_t*)(memory+addr));
          case 4: return load->signed_ ? (int64_t)*((int32_t*)(memory+addr)) : (int64_t)*((uint32_t*)(memory+addr));
          case 8: return load->signed_ ? (int64_t)*((int64_t*)(memory+addr)) : (int64_t)*((uint64_t*)(memory+addr));
          default: abort();
        }
        break;
      }
      case f32: return *((float*)(memory+addr));
      case f64: return *((double*)(memory+addr));
      default: abort();
    }
  }

  void store(Store* store, size_t addr, Literal value) override {
    // ignore align - assume we are on x86 etc. which does that
    switch (store->type) {
      case i32: {
        switch (store->bytes) {
          case 1: *((int8_t*)(memory+addr)) = value.geti32(); break;
          case 2: *((int16_t*)(memory+addr)) = value.geti32(); break;
          case 4: *((int32_t*)(memory+addr)) = value.geti32(); break;
          default: abort();
        }
        break;
      }
      case i64: {
        switch (store->bytes) {
          case 1: *((int8_t*)(memory+addr)) = value.geti64(); break;
          case 2: *((int16_t*)(memory+addr)) = value.geti64(); break;
          case 4: *((int32_t*)(memory+addr)) = value.geti64(); break;
          case 8: *((int64_t*)(memory+addr)) = value.geti64(); break;
          default: abort();
        }
        break;
      }
      // write floats carefully, ensuring all bits reach memory
      case f32: *((int32_t*)(memory+addr)) = value.reinterpreti32(); break;
      case f64: *((int64_t*)(memory+addr)) = value.reinterpreti64(); break;
      default: abort();
    }
  }

  void growMemory(size_t oldSize, size_t newSize) override {
    memory = (char*)realloc(memory, newSize);
    if (newSize > oldSize) {
      memset(memory + oldSize, 0, newSize - oldSize);
    }
  }

  jmp_buf trapState;

  void trap(const char* why) override {
    std::cerr << "[trap " << why << "]\n";
    longjmp(trapState, 1);
  }
};

//
// An invocation into a module
//

struct Invocation {
  ModuleInstance* instance;
  IString name;
  ModuleInstance::LiteralList arguments;

  Invocation(Element& invoke, ModuleInstance* instance, SExpressionWasmBuilder& builder) : instance(instance) {
    assert(invoke[0]->str() == INVOKE);
    name = invoke[1]->str();
    for (size_t j = 2; j < invoke.size(); j++) {
      Expression* argument = builder.parseExpression(*invoke[j]);
      arguments.push_back(argument->dyn_cast<Const>()->value);
    }
  }

  Literal invoke() {
    return instance->callExport(name, arguments);
  }
};

static void run_asserts(size_t* i, bool* checked, AllocatingModule* wasm,
                        Element* root,
                        std::unique_ptr<SExpressionWasmBuilder>* builder,
                        bool print_before, bool print_after) {
  auto interface = new ShellExternalInterface();
  auto instance = new ModuleInstance(*wasm, interface);
  while (*i < root->size()) {
    Element& curr = *(*root)[*i];
    IString id = curr[0]->str();
    if (id == MODULE) break;
    *checked = true;
    Colors::red(std::cerr);
    std::cerr << *i << '/' << (root->size()-1);
    Colors::green(std::cerr);
    std::cerr << " CHECKING: ";
    Colors::normal(std::cerr);
    std::cerr << curr << '\n';
    if (id == ASSERT_INVALID) {
      // a module invalidity test
      AllocatingModule wasm;
      bool invalid = false;
      jmp_buf trapState;
      if (setjmp(trapState) == 0) {
        *builder = std::unique_ptr<SExpressionWasmBuilder>(new SExpressionWasmBuilder(wasm, *curr[1], [&]() {
          invalid = true;
          longjmp(trapState, 1);
        }));
      }
      if (print_before || print_after) {
        Colors::bold(std::cout);
        std::cerr << "printing in module invalidity test:\n";
        Colors::normal(std::cout);
        std::cout << wasm;
      }
      if (!invalid) {
        // maybe parsed ok, but otherwise incorrect
        invalid = !WasmValidator().validate(wasm);
      }
      assert(invalid);
    } else if (id == INVOKE) {
      Invocation invocation(curr, instance, *builder->get());
      invocation.invoke();
    } else {
      // an invoke test
      Invocation invocation(*curr[1], instance, *builder->get());
      bool trapped = false;
      Literal result;
      if (setjmp(interface->trapState) == 0) {
        result = invocation.invoke();
      } else {
        trapped = true;
      }
      if (id == ASSERT_RETURN) {
        assert(!trapped);
        if (curr.size() >= 3) {
          Literal expected = builder->get()
                                 ->parseExpression(*curr[2])
                                 ->dyn_cast<Const>()
                                 ->value;
          std::cerr << "seen " << result << ", expected " << expected << '\n';
          assert(expected == result);
        } else {
          Literal expected;
          std::cerr << "seen " << result << ", expected " << expected << '\n';
          assert(expected == result);
        }
      }
      if (id == ASSERT_TRAP) assert(trapped);
    }
    *i += 1;
  }
}

//
// main
//

int main(int argc, char **argv) {
  debug = getenv("BINARYEN_DEBUG") ? getenv("BINARYEN_DEBUG")[0] - '0' : 0;

  char *infile = nullptr;
  bool print_before = false;
  bool print_after = false;
  std::vector<std::string> passes;

  assert(argc > 0 && "expect at least program name as an argument");
  for (size_t i = 1, e = argc; i != e; i++) {
    char* curr = argv[i];
    if (curr[0] == '-') {
      std::string arg = curr;
      if (arg == "-print-before") {
        print_before = true;
      } else if (arg == "-print-after") {
        print_after = true;
      } else if (arg == "--help") {
        std::cout << "\n";
        std::cout << "binaryen shell\n";
        std::cout << "--------------\n\n";
        std::cout << "printing options:\n";
        std::cout << "  -print-before : print modules before processing them\n";
        std::cout << "  -print-after  : print modules after processing them\n";
        std::cout << "\n";
        std::cout << "passes:\n";
        std::cout << "  -O : execute default optimization passes\n";
        auto allPasses = PassRegistry::get()->getRegisteredNames();
        for (auto& name : allPasses) {
          std::cout << "  -" << name << " : " << PassRegistry::get()->getPassDescription(name) << "\n";
        }
        std::cout << "\n";
        exit(0);
      } else if (arg == "-O") {
        passes.push_back("remove-unused-brs");
        passes.push_back("remove-unused-names");
        passes.push_back("merge-blocks");
        passes.push_back("simplify-locals");
      } else {
        // otherwise, assumed to be a pass
        const char* name = curr + 1;
        auto check = PassRegistry::get()->createPass(name);
        if (!check) {
          printf("error: invalid option %s\n", curr);
          exit(1);
        }
        delete check;
        passes.push_back(name);
      }
    } else {
      if (infile) {
        printf("error: too many input files provided.\n");
        exit(1);
      }
      infile = curr;
    }
  }

  if (!infile) {
    printf("error: no input file provided.\n");
    exit(1);
  }

  if (debug) std::cerr << "loading '" << infile << "'...\n";
  FILE *f = fopen(infile, "r");
  if (!f) {
    printf("error: could not open input file: %s\n", infile);
    exit(1);
  }
  fseek(f, 0, SEEK_END);
  int size = ftell(f);
  char *input = new char[size+1];
  rewind(f);
  int num = fread(input, 1, size, f);
  // On Windows, ftell() gives the byte position (\r\n counts as two bytes), but when
  // reading, fread() returns the number of characters read (\r\n is read as one char \n, and counted as one),
  // so return value of fread can be less than size reported by ftell, and that is normal.
  assert((num > 0 || size == 0) && num <= size);
  fclose(f);
  input[num] = 0;

  if (debug) std::cerr << "parsing text to s-expressions...\n";
  SExpressionParser parser(input);
  Element& root = *parser.root;
  if (debug) std::cout << root << '\n';

  // A .wast may have multiple modules, with some asserts after them
  bool checked = false;
  size_t i = 0;
  while (i < root.size()) {
    if (debug) std::cerr << "parsing s-expressions to wasm...\n";
    AllocatingModule wasm;
    std::unique_ptr<SExpressionWasmBuilder> builder(
        new SExpressionWasmBuilder(wasm, *root[i], [&]() { abort(); }, debug));
    i++;

    if (print_before) {
      Colors::bold(std::cout);
      std::cerr << "printing before:\n";
      Colors::normal(std::cout);
      std::cout << wasm;
    }

    MixedArena moreModuleAllocations;

    if (passes.size() > 0) {
      if (debug) std::cerr << "running passes...\n";
      PassRunner passRunner(&moreModuleAllocations);
      for (auto& passName : passes) {
        passRunner.add(passName);
      }
      passRunner.run(&wasm);
    }

    if (print_after) {
      Colors::bold(std::cout);
      std::cerr << "printing after:\n";
      Colors::normal(std::cout);
      std::cout << wasm;
    }

    run_asserts(&i, &checked, &wasm, &root, &builder, print_before,
                print_after);
  }

  if (checked) {
    Colors::green(std::cerr);
    Colors::bold(std::cerr);
    std::cerr << "all checks passed.\n";
    Colors::normal(std::cerr);
  }
}
<commit_msg>--entry option in binaryen-shell, which lets you call an entry point. also support exit()<commit_after>/*
 * Copyright 2015 WebAssembly Community Group participants
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

//
// A WebAssembly shell, loads a .wast file (WebAssembly in S-Expression format)
// and executes it. This provides similar functionality as the reference
// interpreter, like assert_* calls, so it can run the spec test suite.
//

#include <setjmp.h>
#include <memory>

#include "wasm-s-parser.h"
#include "wasm-interpreter.h"
#include "wasm-validator.h"
#include "pass.h"

using namespace cashew;
using namespace wasm;

namespace wasm {
int debug = 0;
}

// Globals

MixedArena globalAllocator;

IString ASSERT_RETURN("assert_return"),
        ASSERT_TRAP("assert_trap"),
        ASSERT_INVALID("assert_invalid"),
        SPECTEST("spectest"),
        PRINT("print"),
        INVOKE("invoke"),
        EXIT("exit");

struct ExitException {
};

//
// Implementation of the shell interpreter execution environment
//

struct ShellExternalInterface : ModuleInstance::ExternalInterface {
  char *memory;

  ShellExternalInterface() : memory(nullptr) {}

  void init(Module& wasm) override {
    memory = (char*)calloc(wasm.memory.initial, 1);
    // apply memory segments
    for (auto segment : wasm.memory.segments) {
      memcpy(memory + segment.offset, segment.data, segment.size);
    }
  }

  Literal callImport(Import *import, ModuleInstance::LiteralList& arguments) override {
    if (import->module == SPECTEST && import->base == PRINT) {
      for (auto argument : arguments) {
        std::cout << argument << '\n';
      }
      return Literal();
    } else if (import->module == ENV && import->base == EXIT) {
      std::cout << "exit()\n";
      throw ExitException();
    }
    std::cout << "callImport " << import->name.str << "\n";
    abort();
  }

  Literal load(Load* load, size_t addr) override {
    // ignore align - assume we are on x86 etc. which does that
    switch (load->type) {
      case i32: {
        switch (load->bytes) {
          case 1: return load->signed_ ? (int32_t)*((int8_t*)(memory+addr))  : (int32_t)*((uint8_t*)(memory+addr));
          case 2: return load->signed_ ? (int32_t)*((int16_t*)(memory+addr)) : (int32_t)*((uint16_t*)(memory+addr));
          case 4: return load->signed_ ? (int32_t)*((int32_t*)(memory+addr)) : (int32_t)*((uint32_t*)(memory+addr));
          default: abort();
        }
        break;
      }
      case i64: {
        switch (load->bytes) {
          case 1: return load->signed_ ? (int64_t)*((int8_t*)(memory+addr))  : (int64_t)*((uint8_t*)(memory+addr));
          case 2: return load->signed_ ? (int64_t)*((int16_t*)(memory+addr)) : (int64_t)*((uint16_t*)(memory+addr));
          case 4: return load->signed_ ? (int64_t)*((int32_t*)(memory+addr)) : (int64_t)*((uint32_t*)(memory+addr));
          case 8: return load->signed_ ? (int64_t)*((int64_t*)(memory+addr)) : (int64_t)*((uint64_t*)(memory+addr));
          default: abort();
        }
        break;
      }
      case f32: return *((float*)(memory+addr));
      case f64: return *((double*)(memory+addr));
      default: abort();
    }
  }

  void store(Store* store, size_t addr, Literal value) override {
    // ignore align - assume we are on x86 etc. which does that
    switch (store->type) {
      case i32: {
        switch (store->bytes) {
          case 1: *((int8_t*)(memory+addr)) = value.geti32(); break;
          case 2: *((int16_t*)(memory+addr)) = value.geti32(); break;
          case 4: *((int32_t*)(memory+addr)) = value.geti32(); break;
          default: abort();
        }
        break;
      }
      case i64: {
        switch (store->bytes) {
          case 1: *((int8_t*)(memory+addr)) = value.geti64(); break;
          case 2: *((int16_t*)(memory+addr)) = value.geti64(); break;
          case 4: *((int32_t*)(memory+addr)) = value.geti64(); break;
          case 8: *((int64_t*)(memory+addr)) = value.geti64(); break;
          default: abort();
        }
        break;
      }
      // write floats carefully, ensuring all bits reach memory
      case f32: *((int32_t*)(memory+addr)) = value.reinterpreti32(); break;
      case f64: *((int64_t*)(memory+addr)) = value.reinterpreti64(); break;
      default: abort();
    }
  }

  void growMemory(size_t oldSize, size_t newSize) override {
    memory = (char*)realloc(memory, newSize);
    if (newSize > oldSize) {
      memset(memory + oldSize, 0, newSize - oldSize);
    }
  }

  jmp_buf trapState;

  void trap(const char* why) override {
    std::cerr << "[trap " << why << "]\n";
    longjmp(trapState, 1);
  }
};

//
// An invocation into a module
//

struct Invocation {
  ModuleInstance* instance;
  IString name;
  ModuleInstance::LiteralList arguments;

  Invocation(Element& invoke, ModuleInstance* instance, SExpressionWasmBuilder& builder) : instance(instance) {
    assert(invoke[0]->str() == INVOKE);
    name = invoke[1]->str();
    for (size_t j = 2; j < invoke.size(); j++) {
      Expression* argument = builder.parseExpression(*invoke[j]);
      arguments.push_back(argument->dyn_cast<Const>()->value);
    }
  }

  Literal invoke() {
    return instance->callExport(name, arguments);
  }
};

static void run_asserts(size_t* i, bool* checked, AllocatingModule* wasm,
                        Element* root,
                        std::unique_ptr<SExpressionWasmBuilder>* builder,
                        bool print_before, bool print_after,
                        Name entry) {
  auto interface = new ShellExternalInterface();
  auto instance = new ModuleInstance(*wasm, interface);
  if (entry.is() > 0) {
    ModuleInstance::LiteralList arguments;
    try {
      instance->callExport(entry, arguments);
    } catch (ExitException& x) {
    }
  }
  while (*i < root->size()) {
    Element& curr = *(*root)[*i];
    IString id = curr[0]->str();
    if (id == MODULE) break;
    *checked = true;
    Colors::red(std::cerr);
    std::cerr << *i << '/' << (root->size()-1);
    Colors::green(std::cerr);
    std::cerr << " CHECKING: ";
    Colors::normal(std::cerr);
    std::cerr << curr << '\n';
    if (id == ASSERT_INVALID) {
      // a module invalidity test
      AllocatingModule wasm;
      bool invalid = false;
      jmp_buf trapState;
      if (setjmp(trapState) == 0) {
        *builder = std::unique_ptr<SExpressionWasmBuilder>(new SExpressionWasmBuilder(wasm, *curr[1], [&]() {
          invalid = true;
          longjmp(trapState, 1);
        }));
      }
      if (print_before || print_after) {
        Colors::bold(std::cout);
        std::cerr << "printing in module invalidity test:\n";
        Colors::normal(std::cout);
        std::cout << wasm;
      }
      if (!invalid) {
        // maybe parsed ok, but otherwise incorrect
        invalid = !WasmValidator().validate(wasm);
      }
      assert(invalid);
    } else if (id == INVOKE) {
      Invocation invocation(curr, instance, *builder->get());
      invocation.invoke();
    } else {
      // an invoke test
      Invocation invocation(*curr[1], instance, *builder->get());
      bool trapped = false;
      Literal result;
      if (setjmp(interface->trapState) == 0) {
        result = invocation.invoke();
      } else {
        trapped = true;
      }
      if (id == ASSERT_RETURN) {
        assert(!trapped);
        if (curr.size() >= 3) {
          Literal expected = builder->get()
                                 ->parseExpression(*curr[2])
                                 ->dyn_cast<Const>()
                                 ->value;
          std::cerr << "seen " << result << ", expected " << expected << '\n';
          assert(expected == result);
        } else {
          Literal expected;
          std::cerr << "seen " << result << ", expected " << expected << '\n';
          assert(expected == result);
        }
      }
      if (id == ASSERT_TRAP) assert(trapped);
    }
    *i += 1;
  }
}

//
// main
//

int main(int argc, char **argv) {
  debug = getenv("BINARYEN_DEBUG") ? getenv("BINARYEN_DEBUG")[0] - '0' : 0;

  char *infile = nullptr;
  bool print_before = false;
  bool print_after = false;
  std::vector<std::string> passes;
  Name entry;

  assert(argc > 0 && "expect at least program name as an argument");
  for (size_t i = 1, e = argc; i != e; i++) {
    char* curr = argv[i];
    if (curr[0] == '-') {
      std::string arg = curr;
      if (arg == "-print-before") {
        print_before = true;
      } else if (arg == "-print-after") {
        print_after = true;
      } else if (arg == "--help") {
        std::cout << "\n";
        std::cout << "binaryen shell\n";
        std::cout << "--------------\n\n";
        std::cout << "printing options:\n";
        std::cout << "  -print-before : print modules before processing them\n";
        std::cout << "  -print-after  : print modules after processing them\n";
        std::cout << "\n";
        std::cout << "execution options:\n";
        std::cout << "  --entry=[ENTRY] : call ENTRY() after parsing the module\n";
        std::cout << "\n";
        std::cout << "passes:\n";
        std::cout << "  -O : execute default optimization passes\n";
        auto allPasses = PassRegistry::get()->getRegisteredNames();
        for (auto& name : allPasses) {
          std::cout << "  -" << name << " : " << PassRegistry::get()->getPassDescription(name) << "\n";
        }
        std::cout << "\n";
        exit(0);
      } else if (arg == "-O") {
        passes.push_back("remove-unused-brs");
        passes.push_back("remove-unused-names");
        passes.push_back("merge-blocks");
        passes.push_back("simplify-locals");
      } else if (arg.substr(0, 7) == "--entry") {
        entry = Name(strchr(curr, '=') + 1);
      } else {
        // otherwise, assumed to be a pass
        const char* name = curr + 1;
        auto check = PassRegistry::get()->createPass(name);
        if (!check) {
          printf("error: invalid option %s\n", curr);
          exit(1);
        }
        delete check;
        passes.push_back(name);
      }
    } else {
      if (infile) {
        printf("error: too many input files provided.\n");
        exit(1);
      }
      infile = curr;
    }
  }

  if (!infile) {
    printf("error: no input file provided.\n");
    exit(1);
  }

  if (debug) std::cerr << "loading '" << infile << "'...\n";
  FILE *f = fopen(infile, "r");
  if (!f) {
    printf("error: could not open input file: %s\n", infile);
    exit(1);
  }
  fseek(f, 0, SEEK_END);
  int size = ftell(f);
  char *input = new char[size+1];
  rewind(f);
  int num = fread(input, 1, size, f);
  // On Windows, ftell() gives the byte position (\r\n counts as two bytes), but when
  // reading, fread() returns the number of characters read (\r\n is read as one char \n, and counted as one),
  // so return value of fread can be less than size reported by ftell, and that is normal.
  assert((num > 0 || size == 0) && num <= size);
  fclose(f);
  input[num] = 0;

  if (debug) std::cerr << "parsing text to s-expressions...\n";
  SExpressionParser parser(input);
  Element& root = *parser.root;
  if (debug) std::cout << root << '\n';

  // A .wast may have multiple modules, with some asserts after them
  bool checked = false;
  size_t i = 0;
  while (i < root.size()) {
    if (debug) std::cerr << "parsing s-expressions to wasm...\n";
    AllocatingModule wasm;
    std::unique_ptr<SExpressionWasmBuilder> builder(
        new SExpressionWasmBuilder(wasm, *root[i], [&]() { abort(); }, debug));
    i++;

    if (print_before) {
      Colors::bold(std::cout);
      std::cerr << "printing before:\n";
      Colors::normal(std::cout);
      std::cout << wasm;
    }

    MixedArena moreModuleAllocations;

    if (passes.size() > 0) {
      if (debug) std::cerr << "running passes...\n";
      PassRunner passRunner(&moreModuleAllocations);
      for (auto& passName : passes) {
        passRunner.add(passName);
      }
      passRunner.run(&wasm);
    }

    if (print_after) {
      Colors::bold(std::cout);
      std::cerr << "printing after:\n";
      Colors::normal(std::cout);
      std::cout << wasm;
    }

    run_asserts(&i, &checked, &wasm, &root, &builder, print_before,
                print_after, entry);
  }

  if (checked) {
    Colors::green(std::cerr);
    Colors::bold(std::cerr);
    std::cerr << "all checks passed.\n";
    Colors::normal(std::cerr);
  }
}
<|endoftext|>


<commit_before>#include "LadderQueue.hpp"
#include <cassert>

namespace warped {

LadderQueue::LadderQueue() {

    /* Initialize the variables */
    std::fill_n(bucket_width_, MAX_RUNG_CNT, 0);
    std::fill_n(rung_bucket_cnt_, MAX_RUNG_CNT, 0);
    std::fill_n(r_start_, MAX_RUNG_CNT, 0);
    std::fill_n(r_current_, MAX_RUNG_CNT, 0);

    /* Create buckets for 2nd rung onwards */
    for (unsigned int rung_index = 1; rung_index < MAX_RUNG_CNT; rung_index++) {
        for (unsigned int bucket_index = 0; bucket_index < MAX_BUCKET_CNT; bucket_index++) {
            rung_[rung_index][bucket_index] =
                        std::make_shared<std::list<std::shared_ptr<Event>>>();
        }
    }
}

std::shared_ptr<Event> LadderQueue::begin() {

    /* Remove from bottom if not empty */
    if (!bottom_.empty()) {
        return *bottom_.begin();
    }

    /* If rungs exist, remove from rungs */
    unsigned int bucket_index = 0;
    if (n_rung_ && !recurseRung(&bucket_index)) {
        /* Check whether rungs still exist */
        if (n_rung_) assert(0);
    }

    /* Check required because rung recursion can affect n_rung_ value */
    if (n_rung_) {
        for (auto event : *rung_[n_rung_-1][bucket_index]) {
            bottom_.insert(event);
        }
        rung_[n_rung_-1][bucket_index]->clear();

        /* If bucket returned is the last valid rung of the bucket */
        if (rung_bucket_cnt_[n_rung_-1] == bucket_index+1) {
            do {
                rung_bucket_cnt_[n_rung_-1] = 0;
                r_start_[n_rung_-1]         = 0;
                r_current_[n_rung_-1]       = 0;
                bucket_width_[n_rung_-1]    = 0;
                n_rung_--;
            } while(n_rung_ && !rung_bucket_cnt_[n_rung_-1]);

        } else {
            while((++bucket_index < rung_bucket_cnt_[n_rung_-1]) &&
                                    rung_[n_rung_-1][bucket_index]->empty());
            if (bucket_index < rung_bucket_cnt_[n_rung_-1]) {
                r_current_[n_rung_-1] =
                    r_start_[n_rung_-1] + bucket_index*bucket_width_[n_rung_-1];
            } else {
                assert(0);
            }
        }

        if (bottom_.empty()) return nullptr;
        return *bottom_.begin();
    }

    /* Check if top has any events before proceeding further*/
    if (top_.empty()) return nullptr;

    /* Move from top to top of empty ladder */
    /* Check if failed to create the first rung */
    bool is_bucket_width_static = false;
    if (!createNewRung(top_.size(), min_ts_, &is_bucket_width_static)) {
        assert(0);
    }

    /* Transfer events from Top to 1st rung of Ladder */
    /* Note: No need to update rCur[0] since it will be equal to rStart[0] initially. */
    for (auto iter = top_.begin(); iter != top_.end();) {
        assert((*iter)->timestamp() >= r_start_[0]);
        bucket_index = std::min(
                (unsigned int)((*iter)->timestamp()-r_start_[0]) / bucket_width_[0],
                                                                        RUNG_BUCKET_CNT(0)-1);
        rung_[0][bucket_index]->push_front(*iter);
        iter = top_.erase(iter);

        /* Update the numBucket parameter */
        if (rung_bucket_cnt_[0] < bucket_index+1) {
            rung_bucket_cnt_[0] = bucket_index+1;
        }
    }

    /* Copy events from bucket_k into Bottom */
    if (!recurseRung(&bucket_index)) {
        assert(0);
    }

    for (auto event : *rung_[n_rung_-1][bucket_index]) {
        bottom_.insert(event);
    }
    rung_[n_rung_-1][bucket_index]->clear();

    /* If bucket returned is the last valid rung of the bucket */
    if (rung_bucket_cnt_[n_rung_-1] == bucket_index+1) {
        rung_bucket_cnt_[n_rung_-1] = 0;
        r_start_[n_rung_-1]         = 0;
        r_current_[n_rung_-1]       = 0;
        bucket_width_[n_rung_-1]    = 0;
        n_rung_--;

    } else {
        while((++bucket_index < rung_bucket_cnt_[n_rung_-1]) &&
                (rung_[n_rung_-1][bucket_index]->empty()));
        if (bucket_index < rung_bucket_cnt_[n_rung_-1]) {
            r_current_[n_rung_-1] =
                r_start_[n_rung_-1] + bucket_index*bucket_width_[n_rung_-1];
        } else {
            rung_bucket_cnt_[n_rung_-1] = 0;
            r_start_[n_rung_-1]         = 0;
            r_current_[n_rung_-1]       = 0;
            bucket_width_[n_rung_-1]    = 0;
            n_rung_--;
        }
    }

    if (bottom_.empty()) return nullptr;
    return *bottom_.begin();
}

void LadderQueue::erase(std::shared_ptr<Event> event) {

    std::cout << event->timestamp();
}

void LadderQueue::insert(std::shared_ptr<Event> event) {

    std::cout << event->timestamp();
}

bool LadderQueue::createNewRung(unsigned int num_events,
                                unsigned int init_start_and_cur_val,
                                bool *is_bucket_width_static) {

    std::cout << num_events << init_start_and_cur_val << *is_bucket_width_static;
    return true;
}

bool LadderQueue::createRungForBottomTransfer(unsigned int start_val) {

    std::cout << start_val;
    return true;
}

bool LadderQueue::recurseRung( unsigned int *index ) {

    std::cout << *index;
    return true;
}

} // namespace warped
<commit_msg>ladder insert definition<commit_after>#include "LadderQueue.hpp"
#include <cassert>

namespace warped {

LadderQueue::LadderQueue() {

    /* Initialize the variables */
    std::fill_n(bucket_width_, MAX_RUNG_CNT, 0);
    std::fill_n(rung_bucket_cnt_, MAX_RUNG_CNT, 0);
    std::fill_n(r_start_, MAX_RUNG_CNT, 0);
    std::fill_n(r_current_, MAX_RUNG_CNT, 0);

    /* Create buckets for 2nd rung onwards */
    for (unsigned int rung_index = 1; rung_index < MAX_RUNG_CNT; rung_index++) {
        for (unsigned int bucket_index = 0; bucket_index < MAX_BUCKET_CNT; bucket_index++) {
            rung_[rung_index][bucket_index] =
                        std::make_shared<std::list<std::shared_ptr<Event>>>();
        }
    }
}

std::shared_ptr<Event> LadderQueue::begin() {

    /* Remove from bottom if not empty */
    if (!bottom_.empty()) {
        return *bottom_.begin();
    }

    /* If rungs exist, remove from rungs */
    unsigned int bucket_index = 0;
    if (n_rung_ && !recurseRung(&bucket_index)) {
        /* Check whether rungs still exist */
        if (n_rung_) assert(0);
    }

    /* Check required because rung recursion can affect n_rung_ value */
    if (n_rung_) {
        for (auto event : *rung_[n_rung_-1][bucket_index]) {
            bottom_.insert(event);
        }
        rung_[n_rung_-1][bucket_index]->clear();

        /* If bucket returned is the last valid rung of the bucket */
        if (rung_bucket_cnt_[n_rung_-1] == bucket_index+1) {
            do {
                rung_bucket_cnt_[n_rung_-1] = 0;
                r_start_[n_rung_-1]         = 0;
                r_current_[n_rung_-1]       = 0;
                bucket_width_[n_rung_-1]    = 0;
                n_rung_--;
            } while(n_rung_ && !rung_bucket_cnt_[n_rung_-1]);

        } else {
            while((++bucket_index < rung_bucket_cnt_[n_rung_-1]) &&
                                    rung_[n_rung_-1][bucket_index]->empty());
            if (bucket_index < rung_bucket_cnt_[n_rung_-1]) {
                r_current_[n_rung_-1] =
                    r_start_[n_rung_-1] + bucket_index*bucket_width_[n_rung_-1];
            } else {
                assert(0);
            }
        }

        if (bottom_.empty()) return nullptr;
        return *bottom_.begin();
    }

    /* Check if top has any events before proceeding further*/
    if (top_.empty()) return nullptr;

    /* Move from top to top of empty ladder */
    /* Check if failed to create the first rung */
    bool is_bucket_width_static = false;
    if (!createNewRung(top_.size(), min_ts_, &is_bucket_width_static)) {
        assert(0);
    }

    /* Transfer events from Top to 1st rung of Ladder */
    /* Note: No need to update rCur[0] since it will be equal to rStart[0] initially. */
    for (auto iter = top_.begin(); iter != top_.end();) {
        assert((*iter)->timestamp() >= r_start_[0]);
        bucket_index = std::min(
                (unsigned int)((*iter)->timestamp()-r_start_[0]) / bucket_width_[0],
                                                                        RUNG_BUCKET_CNT(0)-1);
        rung_[0][bucket_index]->push_front(*iter);
        iter = top_.erase(iter);

        /* Update the numBucket parameter */
        if (rung_bucket_cnt_[0] < bucket_index+1) {
            rung_bucket_cnt_[0] = bucket_index+1;
        }
    }

    /* Copy events from bucket_k into Bottom */
    if (!recurseRung(&bucket_index)) {
        assert(0);
    }

    for (auto event : *rung_[n_rung_-1][bucket_index]) {
        bottom_.insert(event);
    }
    rung_[n_rung_-1][bucket_index]->clear();

    /* If bucket returned is the last valid rung of the bucket */
    if (rung_bucket_cnt_[n_rung_-1] == bucket_index+1) {
        rung_bucket_cnt_[n_rung_-1] = 0;
        r_start_[n_rung_-1]         = 0;
        r_current_[n_rung_-1]       = 0;
        bucket_width_[n_rung_-1]    = 0;
        n_rung_--;

    } else {
        while((++bucket_index < rung_bucket_cnt_[n_rung_-1]) &&
                (rung_[n_rung_-1][bucket_index]->empty()));
        if (bucket_index < rung_bucket_cnt_[n_rung_-1]) {
            r_current_[n_rung_-1] =
                r_start_[n_rung_-1] + bucket_index*bucket_width_[n_rung_-1];
        } else {
            rung_bucket_cnt_[n_rung_-1] = 0;
            r_start_[n_rung_-1]         = 0;
            r_current_[n_rung_-1]       = 0;
            bucket_width_[n_rung_-1]    = 0;
            n_rung_--;
        }
    }

    if (bottom_.empty()) return nullptr;
    return *bottom_.begin();
}

void LadderQueue::erase(std::shared_ptr<Event> event) {

    std::cout << event->timestamp();
}

void LadderQueue::insert(std::shared_ptr<Event> event) {

    assert(event != nullptr);
    auto timestamp = event->timestamp();

    /* Insert into top, if valid */
    if (timestamp > top_start_) {  //deviation from APPENDIX of ladderq
        if(top_.empty()) {
            max_ts_ = min_ts_ = timestamp;
        } else {
            if (min_ts_ > timestamp) min_ts_ = timestamp;
            if (max_ts_ < timestamp) max_ts_ = timestamp;
        }
        top_.push_front(event);
        return;
    }

    /* Step through rungs */
    unsigned int rung_index = 0;
    while ((rung_index < n_rung_) && (timestamp < r_current_[rung_index])) {
        rung_index++;
    }

    if (rung_index < n_rung_) {  /* found a rung */
        assert(timestamp >= r_start_[rung_index]);
        unsigned int bucket_index = std::min(
            (unsigned int)(timestamp - r_start_[rung_index]) / bucket_width_[rung_index],
                                                            RUNG_BUCKET_CNT(rung_index)-1);

        /* Adjust rung parameters */
        if (rung_bucket_cnt_[rung_index] < bucket_index+1) {
            rung_bucket_cnt_[rung_index] = bucket_index+1;
        }
        if (r_current_[rung_index] >
                    r_start_[rung_index] + bucket_index*bucket_width_[rung_index]) {
            r_current_[rung_index] =
                    r_start_[rung_index] + bucket_index*bucket_width_[rung_index];
        }

        rung_[rung_index][bucket_index]->push_front(event);
        return;
    }

    /* If bottom exceeds threshold */
    if (bottom_.size() >= THRESHOLD) {
        /* If no additional rungs can be created */
        if (n_rung_ >= MAX_RUNG_CNT) {
            /* Intentionally let the bottom continue to overflow */
            //ref sec 2.4 of ladderq + when bucket width becomes static
            bottom_.insert(event);
            return;
        }

        /* Check if new event to be inserted is smaller than what is present in BOTTOM */
        auto bucket_start_ts = (*bottom_.begin())->timestamp();
        if (bucket_start_ts > timestamp) bucket_start_ts = timestamp;

        assert(createRungForBottomTransfer(bucket_start_ts));

        /* Transfer bottom to new rung */
        for (auto iter = bottom_.begin(); iter != bottom_.end(); iter++) {
            assert( (*iter)->timestamp() >= r_start_[n_rung_-1] );
            unsigned int bucket_index = std::min(
                (unsigned int)(((*iter)->timestamp()-r_start_[n_rung_-1]) /
                                                    bucket_width_[n_rung_-1]),
                                                            RUNG_BUCKET_CNT(n_rung_-1)-1 );

            /* Adjust rung parameters */
            if (rung_bucket_cnt_[n_rung_-1] < bucket_index+1) {
                rung_bucket_cnt_[n_rung_-1] = bucket_index+1;
            }
            rung_[n_rung_-1][bucket_index]->push_front(*iter);
        }
        bottom_.clear();

        /* Insert new element in the new and populated rung */
        assert(timestamp >= r_start_[n_rung_-1]);
        unsigned int bucket_index = std::min(
                (unsigned int)((timestamp-r_start_[n_rung_-1]) / bucket_width_[n_rung_-1]),
                                                            RUNG_BUCKET_CNT(n_rung_-1)-1 );
        if (rung_bucket_cnt_[n_rung_-1] < bucket_index+1) {
            rung_bucket_cnt_[n_rung_-1] = bucket_index+1;
        }
        if (r_current_[n_rung_-1] >
                    r_start_[n_rung_-1] + bucket_index*bucket_width_[n_rung_-1]) {
            r_current_[n_rung_-1] =
                    r_start_[n_rung_-1] + bucket_index*bucket_width_[n_rung_-1];
        }
        rung_[n_rung_-1][bucket_index]->push_front(event);

    } else { /* If BOTTOM is within threshold */
        bottom_.insert(event);
    }
}

bool LadderQueue::createNewRung(unsigned int num_events,
                                unsigned int init_start_and_cur_val,
                                bool *is_bucket_width_static) {

    std::cout << num_events << init_start_and_cur_val << *is_bucket_width_static;
    return true;
}

bool LadderQueue::createRungForBottomTransfer(unsigned int start_val) {

    std::cout << start_val;
    return true;
}

bool LadderQueue::recurseRung( unsigned int *index ) {

    std::cout << *index;
    return true;
}

} // namespace warped
<|endoftext|>


<commit_before>#include <iostream>
#include <fstream>
#include <string>

// Loriano: let's try Armadillo quick code
#include <armadillo>

#define ENTDIM 8
#define COORDIM (ENTDIM-2)

namespace
{
  int numofline (const char * fname)
  {
    int number_of_lines = 0;
    std::string line;
    std::ifstream myfile(fname);

    while (std::getline(myfile, line))
      ++number_of_lines;

    myfile.close();

    return number_of_lines;
  }
}

int main (int argc, char ** argv)
{
  if (argc != 2)
  {
    std::cerr << "usage: " << argv[0] << " coordinatesfile " << std::endl;
    return 1;
  }

  int num_of_line = numofline(argv[1]);
  std::cout << "file has " << num_of_line << " line " << std::endl;
  int num_of_ent = (num_of_line-1)/ENTDIM;
  std::cout << "  " << num_of_ent << " entries " << std::endl;

  // non perfomante ma easy to go
  double ** param_mtx = new double *[num_of_ent];
  double ** coord_mtx = new double *[num_of_ent];
  for (int i = 0; i < num_of_ent; ++i)
  {
    coord_mtx[i] = new double[3*COORDIM];
    param_mtx[i] = new double[5];
  }

  // leggere file coordinate tracce simulate plus parametri
  std::string line;
  std::ifstream mytfp;
  mytfp.open (argv[1], std::ios::in);

  std::getline (mytfp, line);
  //std::cout << line << std::endl;

  for (int i = 0; i < num_of_ent; ++i)
  {
    int fake1, fake2;
    mytfp >> fake1 >> fake2 ;
#ifdef DEBUG
    std::cout << fake1 << " " << fake2 << std::endl;
#endif
    for (int j = 0; j < COORDIM; ++j)
    {
      int a, b, c;
      mytfp >> coord_mtx[i][j*3] >>
               coord_mtx[i][j*3+1] >>
               coord_mtx[i][j*3+2] >>
               a >> b >> c;
    }
    mytfp >> param_mtx[i][0] >>
             param_mtx[i][1] >>
             param_mtx[i][2] >>
             param_mtx[i][3] >>
             param_mtx[i][4];
  }

  mytfp.close();

#ifdef DEBUG
  for (int i = 0; i < num_of_ent; ++i)
  {
    for (int j = 0; j < COORDIM; ++j)
    {
      std::cout << coord_mtx[i][j*3] << " " <<
                   coord_mtx[i][j*3+1] << " " <<
                   coord_mtx[i][j*3+2] << std::endl;
    }
    std::cout << param_mtx[i][0] << " " <<
                 param_mtx[i][1] << " " <<
                 param_mtx[i][2] << " " <<
                 param_mtx[i][3] << " " <<
                 param_mtx[i][4] << std::endl;
  }
#endif

  double sum = 1.0e0;
  double coordm[3*COORDIM] = {0.0e0};
  double hc[3*COORDIM][3*COORDIM] = {0.0e0};

  for (int l=0; l<num_of_ent; ++l)
  {
    sum += 1.0e0;
    for (int i=0; i<(3*COORDIM); ++i)
      coordm[i] += (coord_mtx[l][i]-coordm[i])/sum;

    for (int i=0; i<(3*COORDIM); ++i)
    {
      for (int j=0; j<(3*COORDIM); ++j)
      {
        hc[i][j] += ((coord_mtx[l][i] - coordm[i])*
                     (coord_mtx[l][j] - coordm[j])-
                     (sum-1.0e0)*hc[i][j]/sum)/(sum-1.0e0);
      }
    }
  }

  for (int i=0; i<(3*COORDIM); ++i)
    for (int j=i+1; j<(3*COORDIM); ++j)
      if (hc[i][j] != hc[j][i])
        std::cout << i << " " << j << " " <<
          hc[i][j] << " ERROR" << std::endl;;

  arma::mat hca = arma::zeros<arma::mat>(3*COORDIM,3*COORDIM);
  for (int i=0; i<(3*COORDIM); ++i)
    for (int j=0; j<(3*COORDIM); ++j)
      hca(i,j) = hc[i][j];

  arma::vec eigval;
  arma::mat eigvec;

  arma::eig_sym(eigval, eigvec, hca);

  double totval = 0.0e0;
  for (int i=0; i<(3*COORDIM); ++i)
    totval += eigval(i);

  int j = 1;
  double totvar = 0.0e0;
  for (int i=(3*COORDIM-1); i>=0; --i)
  {
    if (j <= 5)
      totvar += 100.0e0*(eigval(i)/totval);
    ++j;

    std::cout << i+1 << " ==> " << 100.0e0*(eigval(i)/totval) << std::endl;
  }
  std::cout << "5 eigenvalues: " << totvar << std::endl;

  // documento Annovi
  // calcolo matrice di correlazione traccie HC
  // diagonalizzo HC e determino A, matrice 5 autovettori principali (5 componenti pricipali)
  // A matrice rotazione che mi permette di calcolare la traslazione usando i paamtri di tracce
  // simulate.

  // documento ATLAS
  // calcolare V e data V calcolare inversa V e quindi C, matrice di rotazione
  // data C determinare il vettore di traslazione q
  // c plus q costanti PCA
  // write constants in a file

  for (int i = 0; i < num_of_ent; ++i)
  {
    delete(coord_mtx[i]);
    delete(param_mtx[i]);
  }
  delete(coord_mtx);
  delete(param_mtx);

  return 0;
}
<commit_msg>quick note (i.e. pseudocode like)<commit_after>#include <iostream>
#include <fstream>
#include <string>

// Loriano: let's try Armadillo quick code
#include <armadillo>

#define ENTDIM 8
#define COORDIM (ENTDIM-2)

namespace
{
  int numofline (const char * fname)
  {
    int number_of_lines = 0;
    std::string line;
    std::ifstream myfile(fname);

    while (std::getline(myfile, line))
      ++number_of_lines;

    myfile.close();

    return number_of_lines;
  }
}

int main (int argc, char ** argv)
{
  if (argc != 2)
  {
    std::cerr << "usage: " << argv[0] << " coordinatesfile " << std::endl;
    return 1;
  }

  int num_of_line = numofline(argv[1]);
  std::cout << "file has " << num_of_line << " line " << std::endl;
  int num_of_ent = (num_of_line-1)/ENTDIM;
  std::cout << "  " << num_of_ent << " entries " << std::endl;

  // non perfomante ma easy to go
  double ** param_mtx = new double *[num_of_ent];
  double ** coord_mtx = new double *[num_of_ent];
  for (int i = 0; i < num_of_ent; ++i)
  {
    coord_mtx[i] = new double[3*COORDIM];
    param_mtx[i] = new double[5];
  }

  // leggere file coordinate tracce simulate plus parametri
  std::string line;
  std::ifstream mytfp;
  mytfp.open (argv[1], std::ios::in);

  std::getline (mytfp, line);
  //std::cout << line << std::endl;

  for (int i = 0; i < num_of_ent; ++i)
  {
    int fake1, fake2;
    mytfp >> fake1 >> fake2 ;
#ifdef DEBUG
    std::cout << fake1 << " " << fake2 << std::endl;
#endif
    for (int j = 0; j < COORDIM; ++j)
    {
      int a, b, c;
      mytfp >> coord_mtx[i][j*3] >>
               coord_mtx[i][j*3+1] >>
               coord_mtx[i][j*3+2] >>
               a >> b >> c;
    }
    mytfp >> param_mtx[i][0] >>
             param_mtx[i][1] >>
             param_mtx[i][2] >>
             param_mtx[i][3] >>
             param_mtx[i][4];
  }

  mytfp.close();

#ifdef DEBUG
  for (int i = 0; i < num_of_ent; ++i)
  {
    for (int j = 0; j < COORDIM; ++j)
    {
      std::cout << coord_mtx[i][j*3] << " " <<
                   coord_mtx[i][j*3+1] << " " <<
                   coord_mtx[i][j*3+2] << std::endl;
    }
    std::cout << param_mtx[i][0] << " " <<
                 param_mtx[i][1] << " " <<
                 param_mtx[i][2] << " " <<
                 param_mtx[i][3] << " " <<
                 param_mtx[i][4] << std::endl;
  }
#endif

  double sum = 1.0e0;
  double coordm[3*COORDIM] = {0.0e0};
  double hc[3*COORDIM][3*COORDIM] = {0.0e0};

  for (int l=0; l<num_of_ent; ++l)
  {
    sum += 1.0e0;
    for (int i=0; i<(3*COORDIM); ++i)
      coordm[i] += (coord_mtx[l][i]-coordm[i])/sum;

    for (int i=0; i<(3*COORDIM); ++i)
    {
      for (int j=0; j<(3*COORDIM); ++j)
      {
        hc[i][j] += ((coord_mtx[l][i] - coordm[i])*
                     (coord_mtx[l][j] - coordm[j])-
                     (sum-1.0e0)*hc[i][j]/sum)/(sum-1.0e0);
      }
    }
  }

  for (int i=0; i<(3*COORDIM); ++i)
    for (int j=i+1; j<(3*COORDIM); ++j)
      if (hc[i][j] != hc[j][i])
        std::cout << i << " " << j << " " <<
          hc[i][j] << " ERROR" << std::endl;;

  arma::mat hca = arma::zeros<arma::mat>(3*COORDIM,3*COORDIM);
  for (int i=0; i<(3*COORDIM); ++i)
    for (int j=0; j<(3*COORDIM); ++j)
      hca(i,j) = hc[i][j];

  arma::vec eigval;
  arma::mat eigvec;

  arma::eig_sym(eigval, eigvec, hca);

  double totval = 0.0e0;
  for (int i=0; i<(3*COORDIM); ++i)
    totval += eigval(i);

  int j = 1;
  double totvar = 0.0e0;
  for (int i=(3*COORDIM-1); i>=0; --i)
  {
    if (j <= 5)
      totvar += 100.0e0*(eigval(i)/totval);
    ++j;

    std::cout << i+1 << " ==> " << 100.0e0*(eigval(i)/totval) << std::endl;
  }
  std::cout << "5 eigenvalues: " << totvar << std::endl;

  arma::mat hcai = arma::zeros<arma::mat>(3*COORDIM,3*COORDIM);
  hcai = hca.i();

  std::cout << hca * hcai ;

  // and so on ...

  // documento Annovi
  // calcolo matrice di correlazione traccie HC
  // diagonalizzo HC e determino A, matrice 5 autovettori principali (5 componenti pricipali)
  // A matrice rotazione che mi permette di calcolare la traslazione usando i paamtri di tracce
  // simulate.

  // documento ATLAS
  // calcolare V e data V calcolare inversa V e quindi C, matrice di rotazione
  // data C determinare il vettore di traslazione q
  // c plus q costanti PCA
  // write constants in a file

  for (int i = 0; i < num_of_ent; ++i)
  {
    delete(coord_mtx[i]);
    delete(param_mtx[i]);
  }
  delete(coord_mtx);
  delete(param_mtx);

  return 0;
}
<|endoftext|>


<commit_before>// Scintilla source code edit control
/** @file LexProgress.cxx
 **  Lexer for Progress 4GL.
 ** Based on LexCPP.cxx of Neil Hodgson <neilh@scintilla.org>
  **/
// Copyright 2006-2007 by Yuval Papish <Yuval@YuvCom.com>
// The License.txt file describes the conditions under which this software may be distributed.

/** TODO:
WebSpeed support in html lexer
Support "end triggers" expression of the triggers phrase
change lmPS to lmProgress
Support more than 6 comments levels
**/
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>

#include "Platform.h"

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

#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif

static inline bool IsAWordChar(int ch) {
	return (ch < 0x80) && (isalnum(ch) || ch == '_');
}

static inline bool IsAWordStart(int ch) {
	return (ch < 0x80) && (isalpha(ch) || ch == '_');
}

enum SentenceStart { SetSentenceStart = 0xf, ResetSentenceStart = 0x10}; // true -> bit5 = 0

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

    WordList &keywords1 = *keywordlists[0];   // regular keywords
    WordList &keywords2 = *keywordlists[1];   // block opening keywords, only when SentenceStart
    WordList &keywords3 = *keywordlists[2];   // block opening keywords
    //WordList &keywords4 = *keywordlists[3]; // preprocessor keywords. Not implemented

	int visibleChars = 0;
	int sentenceStartState; // true -> bit5 = 0

	StyleContext sc(startPos, length, initStyle, styler);

	for (; sc.More(); sc.Forward()) {

		if (sc.atLineStart) {
			// Reset states to begining of colourise so no surprises
			// if different sets of lines lexed.
			visibleChars = 0;
		}

		// Handle line continuation generically.
		if (sc.ch == '~') {
			if (sc.chNext > ' ') {
				// skip special char after ~
				sc.Forward();
				continue;
			}
			else {
				// Skip whitespace between ~ and EOL
				while (sc.More() && (sc.chNext == ' ' || sc.chNext == '\t') ) {
					sc.Forward();
				}
				if (sc.chNext == '\n' || sc.chNext == '\r') {
					sc.Forward();
					if (sc.ch == '\r' && sc.chNext == '\n') {
						sc.Forward();
					}
					sc.Forward();
					continue;
				}
			}
		}
		// Determine if a new state should be terminated.
		sentenceStartState = sc.state & 0x10;
		switch (sc.state & 0xf) {
			case SCE_4GL_OPERATOR:
				sc.SetState(SCE_4GL_DEFAULT | sentenceStartState);
				break;
			case SCE_4GL_NUMBER:
				if (!(IsADigit(sc.ch))) {
					sc.SetState(SCE_4GL_DEFAULT | sentenceStartState);
				}
				break;
			case SCE_4GL_IDENTIFIER:
				if (!IsAWordChar(sc.ch) && sc.ch != '-') {
					char s[1000];
					sc.GetCurrentLowered(s, sizeof(s));
					if (((sentenceStartState == 0) && keywords2.InList(s)) || keywords3.InList(s)) {
						sc.ChangeState(SCE_4GL_BLOCK | ResetSentenceStart);
					}
					else if (keywords1.InList(s)) {
						if ((s[0] == 'e' && s[1] =='n' && s[2] == 'd' && !isalnum(s[3]) && s[3] != '-') ||
							(s[0] == 'f' && s[1] =='o' && s[2] == 'r' && s[3] == 'w' && s[4] =='a' && s[5] == 'r' && s[6] == 'd'&& !isalnum(s[7]))) {
							sc.ChangeState(SCE_4GL_END | ResetSentenceStart);
						}
						else if	((s[0] == 'e' && s[1] =='l' && s[2] == 's' && s[3] == 'e') ||
								 (s[0] == 't' && s[1] =='h' && s[2] == 'e' && s[3] == 'n')) {
							sc.ChangeState(SCE_4GL_WORD & SetSentenceStart);
						}
						else {
							sc.ChangeState(SCE_4GL_WORD | ResetSentenceStart);
						}
					}
					sc.SetState(SCE_4GL_DEFAULT | (sc.state & 0x10));
				}
				break;
			case SCE_4GL_PREPROCESSOR:
				if (sc.atLineStart) {
					sc.SetState(SCE_4GL_DEFAULT & SetSentenceStart);
				} else if (sc.ch == '*' && sc.chNext == '/') {
					sc.ForwardSetState(SCE_4GL_DEFAULT | sentenceStartState);
				}
				break;
			case SCE_4GL_STRING:
				if (sc.ch == '\"') {
					sc.ForwardSetState(SCE_4GL_DEFAULT | sentenceStartState);
				}
				break;
			case SCE_4GL_CHARACTER:
				if (sc.ch == '\'') {
					sc.ForwardSetState(SCE_4GL_DEFAULT | sentenceStartState);
				}
				break;
			default:
				if ((sc.state & 0xf) >= SCE_4GL_COMMENT1) {
					if (sc.ch == '*' && sc.chNext == '/') {
						sc.Forward();
						if ((sc.state & 0xf) == SCE_4GL_COMMENT1) {
							sc.ForwardSetState(SCE_4GL_DEFAULT | sentenceStartState);
						}
						else
							sc.SetState((sc.state & 0x1f) - 1);
					} else if (sc.ch == '/' && sc.chNext == '*') {
						sc.Forward();
						sc.SetState((sc.state & 0x1f) + 1);
					}
				}
		}

		// Determine if a new state should be entered.
		sentenceStartState = sc.state & 0x10;
		if ((sc.state & 0xf) == SCE_4GL_DEFAULT) {
			if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
				sc.SetState(SCE_4GL_NUMBER | ResetSentenceStart);
			} else if (IsAWordStart(sc.ch) || sc.ch == '@') {
				sc.SetState(SCE_4GL_IDENTIFIER | sentenceStartState);
			} else if (sc.ch == '/' && sc.chNext == '*') {
				sc.SetState(SCE_4GL_COMMENT1 | sentenceStartState);
				sc.Forward();
			} else if (sc.ch == '\"') {
				sc.SetState(SCE_4GL_STRING | ResetSentenceStart);
			} else if (sc.ch == '\'') {
				sc.SetState(SCE_4GL_CHARACTER | ResetSentenceStart);
			} else if (sc.ch == '&' && visibleChars == 0 && ((sc.state & 0x10) == 0)) {
				sc.SetState(SCE_4GL_PREPROCESSOR | ResetSentenceStart);
				// Skip whitespace between & and preprocessor word
				do {
					sc.Forward();
				} while ((sc.ch == ' ' || sc.ch == '\t') && sc.More());
			// Handle syntactical line termination
			} else if ((sc.ch == '.' || sc.ch == ':' || sc.ch == '}') && (sc.chNext == ' ' || sc.chNext == '\t' || sc.chNext == '\n' || sc.chNext == '\r')) {
				sc.SetState(sc.state & SetSentenceStart);
			} else if (isoperator(static_cast<char>(sc.ch))) {
		/* 	This code allows highlight of handles. Alas, it would cause the frase "last-event:function"
			to be recognized as a BlockBegin

				if (sc.ch == ':')
					sc.SetState(SCE_4GL_OPERATOR & SetSentenceStart);
				else */
					sc.SetState(SCE_4GL_OPERATOR | ResetSentenceStart);
			}
		}

		if (!IsASpace(sc.ch)) {
			visibleChars++;
		}
	}
	sc.Complete();
}

static bool IsStreamCommentStyle(int style) {
	return (style & 0xf) >= SCE_4GL_COMMENT1 ;
}

// Store both the current line's fold level and the next lines in the
// level store to make it easy to pick up with each increment
// and to make it possible to fiddle the current level for "} else {".
static void FoldNoBox4glDoc(unsigned int startPos, int length, int initStyle,
                            Accessor &styler) {
	bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
	bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
	bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0;
	unsigned int endPos = startPos + length;
	int visibleChars = 0;
	int lineCurrent = styler.GetLine(startPos);
	int levelCurrent = SC_FOLDLEVELBASE;
	if (lineCurrent > 0)
		levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
	int levelMinCurrent = levelCurrent;
	int levelNext = levelCurrent;
	char chNext = static_cast<char>(tolower(styler[startPos]));
	int styleNext = styler.StyleAt(startPos);
	int style = initStyle;
	for (unsigned int i = startPos; i < endPos; i++) {
		char ch = chNext;
		chNext = static_cast<char>(tolower(styler.SafeGetCharAt(i + 1)));
		int stylePrev = style;
		style = styleNext;
		styleNext = styler.StyleAt(i + 1);
		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
		if (foldComment && IsStreamCommentStyle(style)) {
			if (!IsStreamCommentStyle(stylePrev)) {
				levelNext++;
			} else if (!IsStreamCommentStyle(styleNext)) { // && !atEOL) {
				// Comments don't end at end of line and the next character may be unstyled.
				levelNext--;
			}
		}
		else if ((style & 0xf) == SCE_4GL_BLOCK && !isalnum(chNext)) {
			levelNext++;
		}
		else if ((style & 0xf) == SCE_4GL_END  && (ch == 'e' || ch == 'f')) {
			levelNext--;
		}
		if (atEOL) {
			int levelUse = levelCurrent;
			if (foldAtElse) {
				levelUse = levelMinCurrent;
			}
			int lev = levelUse | levelNext << 16;
			if (visibleChars == 0 && foldCompact)
				lev |= SC_FOLDLEVELWHITEFLAG;
			if (levelUse < levelNext)
				lev |= SC_FOLDLEVELHEADERFLAG;
			if (lev != styler.LevelAt(lineCurrent)) {
				styler.SetLevel(lineCurrent, lev);
			}
			lineCurrent++;
			levelCurrent = levelNext;
			levelMinCurrent = levelCurrent;
			visibleChars = 0;
		}
		if (!isspacechar(ch))
			visibleChars++;
	}
}

static void Fold4glDoc(unsigned int startPos, int length, int initStyle, WordList *[],
                       Accessor &styler) {
	FoldNoBox4glDoc(startPos, length, initStyle, styler);
}

static const char * const FglWordLists[] = {
            "Primary keywords and identifiers",
            "Secondary keywords and identifiers",
            "Documentation comment keywords",
            "Unused",
            "Global classes and typedefs",
            0,
        };

LexerModule lmProgress(SCLEX_PROGRESS, Colourise4glDoc, "progress", Fold4glDoc, FglWordLists);
<commit_msg>Feature request #2902206 from Yuval. Improve handling of comments in preprocessor declaration Cleaning code Improve documentation<commit_after>// Scintilla source code edit control
/** @file LexProgress.cxx
 **  Lexer for Progress 4GL.
 ** Based on LexCPP.cxx of Neil Hodgson <neilh@scintilla.org>
  **/
// Copyright 2006-2007 by Yuval Papish <Yuval@YuvCom.com>
// The License.txt file describes the conditions under which this software may be distributed.

/** TODO:
WebSpeed support in html lexer
Support "end triggers" expression of the triggers phrase
Support more than 6 comments levels
**/
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>

#include "Platform.h"

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

#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif

static inline bool IsAWordChar(int ch) {
	return (ch < 0x80) && (isalnum(ch) || ch == '_');
}

static inline bool IsAWordStart(int ch) {
	return (ch < 0x80) && (isalpha(ch) || ch == '_');
}

enum SentenceStart { SetSentenceStart = 0xf, ResetSentenceStart = 0x10}; // true -> bit = 0

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

    WordList &keywords1 = *keywordlists[0];   // regular keywords
    WordList &keywords2 = *keywordlists[1];   // block opening keywords, only when SentenceStart
    WordList &keywords3 = *keywordlists[2];   // block opening keywords
    //WordList &keywords4 = *keywordlists[3]; // preprocessor keywords. Not implemented

	int visibleChars = 0;
	int mask;

	StyleContext sc(startPos, length, initStyle, styler);

	for (; sc.More(); sc.Forward()) {

		if (sc.atLineStart) {
			// Reset states to begining of colourise so no surprises
			// if different sets of lines lexed.
			visibleChars = 0;
		}

		// Handle line continuation generically.
		if ((sc.state & 0xf) < SCE_4GL_COMMENT1) {
		if (sc.ch == '~') {
			if (sc.chNext > ' ') {
				// skip special char after ~
				sc.Forward();
				continue;
			}
			else {
				// Skip whitespace between ~ and EOL
				while (sc.More() && (sc.chNext == ' ' || sc.chNext == '\t') ) {
					sc.Forward();
				}
				if (sc.chNext == '\n' || sc.chNext == '\r') {
					sc.Forward();
					if (sc.ch == '\r' && sc.chNext == '\n') {
						sc.Forward();
					}
					sc.Forward();
					continue;
				}
			}
		}
		}
		// Determine if a new state should be terminated.
		mask = sc.state & 0x10;
		switch (sc.state & 0xf) {
			case SCE_4GL_OPERATOR:
				sc.SetState(SCE_4GL_DEFAULT | mask);
				break;
			case SCE_4GL_NUMBER:
				if (!(IsADigit(sc.ch))) {
					sc.SetState(SCE_4GL_DEFAULT | mask);
				}
				break;
			case SCE_4GL_IDENTIFIER:
				if (!IsAWordChar(sc.ch) && sc.ch != '-') {
					char s[1000];
					sc.GetCurrentLowered(s, sizeof(s));
					if (((sc.state & 0x10) == 0) && keywords2.InList(s) || keywords3.InList(s)) {
						sc.ChangeState(SCE_4GL_BLOCK | ResetSentenceStart);
					}
					else if (keywords1.InList(s)) {
						if ((s[0] == 'e' && s[1] =='n' && s[2] == 'd' && !isalnum(s[3]) && s[3] != '-') ||
							(s[0] == 'f' && s[1] =='o' && s[2] == 'r' && s[3] == 'w' && s[4] =='a' && s[5] == 'r' && s[6] == 'd'&& !isalnum(s[7]))) {
							sc.ChangeState(SCE_4GL_END | ResetSentenceStart);
						}
						else if	((s[0] == 'e' && s[1] =='l' && s[2] == 's' && s[3] == 'e') ||
								 (s[0] == 't' && s[1] =='h' && s[2] == 'e' && s[3] == 'n')) {
							sc.ChangeState(SCE_4GL_WORD & SetSentenceStart);
						}
						else {
							sc.ChangeState(SCE_4GL_WORD | ResetSentenceStart);
						}
					}
					sc.SetState(SCE_4GL_DEFAULT | (sc.state & 0x10));
				}
				break;
			case SCE_4GL_PREPROCESSOR:
				if (sc.atLineStart) {
					sc.SetState(SCE_4GL_DEFAULT & SetSentenceStart);
				}
				/* code removed to allow comments inside preprocessor
					else if (sc.ch == '*' && sc.chNext == '/') {
					sc.ForwardSetState(SCE_4GL_DEFAULT | sentenceStartState); } */
				break;
			case SCE_4GL_STRING:
				if (sc.ch == '\"') {
					sc.ForwardSetState(SCE_4GL_DEFAULT | mask);
				}
				break;
			case SCE_4GL_CHARACTER:
				if (sc.ch == '\'') {
					sc.ForwardSetState(SCE_4GL_DEFAULT | mask);
				}
				break;
			default:
				if ((sc.state & 0xf) >= SCE_4GL_COMMENT1) {
					if (sc.ch == '*' && sc.chNext == '/') {
						sc.Forward();
						if ((sc.state & 0xf) == SCE_4GL_COMMENT1) {
							sc.ForwardSetState(SCE_4GL_DEFAULT | mask);
						}
						else
							sc.SetState((sc.state & 0x1f) - 1);
					} else if (sc.ch == '/' && sc.chNext == '*') {
						sc.Forward();
						sc.SetState((sc.state & 0x1f) + 1);
					}
				}
		}

		// Determine if a new state should be entered.
		mask = sc.state & 0x10;
		if ((sc.state & 0xf) == SCE_4GL_DEFAULT) {
			if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
				sc.SetState(SCE_4GL_NUMBER | ResetSentenceStart);
			} else if (IsAWordStart(sc.ch) || (sc.ch == '@')) {
				sc.SetState(SCE_4GL_IDENTIFIER | mask);
			} else if (sc.ch == '/' && sc.chNext == '*') {
				sc.SetState(SCE_4GL_COMMENT1 | mask);
				sc.Forward();
			} else if (sc.ch == '\"') {
				sc.SetState(SCE_4GL_STRING | ResetSentenceStart);
			} else if (sc.ch == '\'') {
				sc.SetState(SCE_4GL_CHARACTER | ResetSentenceStart);
			} else if (sc.ch == '&' && visibleChars == 0 && ((sc.state & 0x10) == 0)) {
				sc.SetState(SCE_4GL_PREPROCESSOR | ResetSentenceStart);
				// Skip whitespace between & and preprocessor word
				do {
					sc.Forward();
				} while ((sc.ch == ' ' || sc.ch == '\t') && sc.More());
			// Handle syntactical line termination
			} else if ((sc.ch == '.' || sc.ch == ':' || sc.ch == '}') && (sc.chNext == ' ' || sc.chNext == '\t' || sc.chNext == '\n' || sc.chNext == '\r')) {
				sc.SetState(sc.state & SetSentenceStart);
			} else if (isoperator(static_cast<char>(sc.ch))) {
		/* 	This code allows highlight of handles. Alas, it would cause the phrase "last-event:function"
			to be recognized as a BlockBegin */

				if (sc.ch == ':')
					sc.SetState(SCE_4GL_OPERATOR & SetSentenceStart);
				/* else */
					sc.SetState(SCE_4GL_OPERATOR | ResetSentenceStart);
			}
		}

		if (!IsASpace(sc.ch)) {
			visibleChars++;
		}
	}
	sc.Complete();
}

static bool IsStreamCommentStyle(int style) {
	return (style & 0xf) >= SCE_4GL_COMMENT1 ;
}

// Store both the current line's fold level and the next lines in the
// level store to make it easy to pick up with each increment
// and to make it possible to fiddle the current level for "} else {".
static void FoldNoBox4glDoc(unsigned int startPos, int length, int initStyle,
                            Accessor &styler) {
	bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
	bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
	bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0;
	unsigned int endPos = startPos + length;
	int visibleChars = 0;
	int lineCurrent = styler.GetLine(startPos);
	int levelCurrent = SC_FOLDLEVELBASE;
	if (lineCurrent > 0)
		levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
	int levelMinCurrent = levelCurrent;
	int levelNext = levelCurrent;
	char chNext = static_cast<char>(tolower(styler[startPos]));
	int styleNext = styler.StyleAt(startPos);
	int style = initStyle;
	for (unsigned int i = startPos; i < endPos; i++) {
		char ch = chNext;
		chNext = static_cast<char>(tolower(styler.SafeGetCharAt(i + 1)));
		int stylePrev = style;
		style = styleNext;
		styleNext = styler.StyleAt(i + 1);
		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
		if (foldComment && IsStreamCommentStyle(style)) {
			if (!IsStreamCommentStyle(stylePrev)) {
				levelNext++;
			} else if (!IsStreamCommentStyle(styleNext)) { // && !atEOL) {
				// Comments don't end at end of line and the next character may be unstyled.
				levelNext--;
			}
		}
		else if ((style & 0xf) == SCE_4GL_BLOCK && !isalnum(chNext)) {
			levelNext++;
		}
		else if ((style & 0xf) == SCE_4GL_END  && (ch == 'e' || ch == 'f')) {
			levelNext--;
		}
		if (atEOL) {
			int levelUse = levelCurrent;
			if (foldAtElse) {
				levelUse = levelMinCurrent;
			}
			int lev = levelUse | levelNext << 16;
			if (visibleChars == 0 && foldCompact)
				lev |= SC_FOLDLEVELWHITEFLAG;
			if (levelUse < levelNext)
				lev |= SC_FOLDLEVELHEADERFLAG;
			if (lev != styler.LevelAt(lineCurrent)) {
				styler.SetLevel(lineCurrent, lev);
			}
			lineCurrent++;
			levelCurrent = levelNext;
			levelMinCurrent = levelCurrent;
			visibleChars = 0;
		}
		if (!isspacechar(ch))
			visibleChars++;
	}
}

static void Fold4glDoc(unsigned int startPos, int length, int initStyle, WordList *[],
                       Accessor &styler) {
	FoldNoBox4glDoc(startPos, length, initStyle, styler);
}

static const char * const FglWordLists[] = {
            "Primary keywords and identifiers",
            "Secondary keywords and identifiers",
            "Documentation comment keywords",
            "Unused",
            "Global classes and typedefs",
            0,
        };

LexerModule lmProgress(SCLEX_PROGRESS, Colourise4glDoc, "progress", Fold4glDoc, FglWordLists);
<|endoftext|>