23#include <rtl/ustring.hxx>
27#include <com/sun/star/drawing/EnhancedCustomShapeParameterType.hpp>
34#define BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE
36#if OSL_DEBUG_LEVEL >= 2 && defined(DBG_UTIL)
37#define BOOST_SPIRIT_DEBUG
39#include <boost/spirit/include/classic_core.hpp>
54 if ( rSource.Value.getValueTypeClass() == uno::TypeClass_DOUBLE )
57 if ( rSource.Value >>= fValue )
58 nValue =
static_cast<sal_Int32
>(fValue);
63 switch( rSource.Type )
65 case css::drawing::EnhancedCustomShapeParameterType::EQUATION :
81 if ( rSource.Type != css::drawing::EnhancedCustomShapeParameterType::NORMAL )
86ExpressionNode::~ExpressionNode()
102 explicit ConstantValueExpression(
double rValue ) :
106 virtual double operator()()
const override
110 virtual bool isConstant()
const override
118 virtual EnhancedCustomShapeParameter fillNode( std::vector< EnhancedCustomShapeEquation >& rEquations,
ExpressionNode* , sal_uInt32 )
override
120 EnhancedCustomShapeParameter aRet;
122 if ( aFract.GetDenominator() == 1 )
124 aRet.Type = EnhancedCustomShapeParameterType::NORMAL;
125 aRet.Value <<= aFract.GetNumerator();
131 aEquation.
nPara[ 0 ] = 1;
132 aEquation.
nPara[ 1 ] =
static_cast<sal_Int16
>(aFract.GetNumerator());
133 aEquation.
nPara[ 2 ] =
static_cast<sal_Int16
>(aFract.GetDenominator());
134 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
135 aRet.Value <<=
static_cast<sal_Int32
>(rEquations.size());
136 rEquations.push_back( aEquation );
151 , mrCustoShape( rCustoShape )
155 virtual double operator()()
const override
159 "$" << mnIndex <<
" --> "
165 virtual bool isConstant()
const override
173 virtual EnhancedCustomShapeParameter fillNode( std::vector< EnhancedCustomShapeEquation >& ,
ExpressionNode* , sal_uInt32 )
override
175 EnhancedCustomShapeParameter aRet;
176 aRet.Type = EnhancedCustomShapeParameterType::ADJUSTMENT;
186 mutable bool mbGettingValueGuard;
192 , mrCustoShape( rCustoShape )
193 , mbGettingValueGuard(false)
196 virtual double operator()()
const override
198 if (mbGettingValueGuard)
200 mbGettingValueGuard =
true;
202 mbGettingValueGuard =
false;
205 virtual bool isConstant()
const override
213 virtual EnhancedCustomShapeParameter fillNode( std::vector< EnhancedCustomShapeEquation >& ,
ExpressionNode* , sal_uInt32 )
override
215 EnhancedCustomShapeParameter aRet;
216 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
217 aRet.Value <<=
mnIndex | 0x40000000;
231 , mrCustoShape ( rCustoShape )
234 virtual double operator()()
const override
237 180.0 * mrCustoShape.
GetEnumFunc(meFunct) / 10800000.0 <<
")");
241 virtual bool isConstant()
const override
249 virtual EnhancedCustomShapeParameter fillNode( std::vector< EnhancedCustomShapeEquation >& rEquations,
ExpressionNode* , sal_uInt32 nFlags )
override
251 EnhancedCustomShapeParameter aRet;
253 aRet.Value <<= sal_Int32(1);
263 ConstantValueExpression aConstantValue( mrCustoShape.
GetEnumFunc( meFunct ) );
264 aRet = aConstantValue.fillNode( rEquations,
nullptr, nFlags );
291 std::shared_ptr<ExpressionNode>
mpArg;
294 UnaryFunctionExpression(
const ExpressionFunct eFunct, std::shared_ptr<ExpressionNode> aArg ) :
316 virtual double operator()()
const override
320 virtual bool isConstant()
const override
322 return mpArg->isConstant();
328 virtual EnhancedCustomShapeParameter fillNode( std::vector< EnhancedCustomShapeEquation >& rEquations,
ExpressionNode* pOptionalArg, sal_uInt32 nFlags )
override
330 EnhancedCustomShapeParameter aRet;
338 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
339 aRet.Value <<=
static_cast<sal_Int32
>(rEquations.size());
340 rEquations.push_back( aEquation );
348 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
349 aRet.Value <<=
static_cast<sal_Int32
>(rEquations.size());
350 rEquations.push_back( aEquation );
360 aEquation.
nPara[ 0 ] = 1;
363 if ( aSource.Type == EnhancedCustomShapeParameterType::NORMAL )
368 aSource.Type = EnhancedCustomShapeParameterType::EQUATION;
369 aSource.Value <<=
static_cast<sal_Int32
>(rEquations.size());
370 rEquations.push_back( _aEquation );
373 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
374 aRet.Value <<=
static_cast<sal_Int32
>(rEquations.size());
375 rEquations.push_back( aEquation );
385 aEquation.
nPara[ 0 ] = 1;
388 if ( aSource.Type == EnhancedCustomShapeParameterType::NORMAL )
393 aSource.Type = EnhancedCustomShapeParameterType::EQUATION;
394 aSource.Value <<=
static_cast<sal_Int32
>(rEquations.size());
395 rEquations.push_back( aTmpEquation );
398 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
399 aRet.Value <<=
static_cast<sal_Int32
>(rEquations.size());
400 rEquations.push_back( aEquation );
410 aEquation.
nPara[ 0 ] = 1;
413 if ( aSource.Type == EnhancedCustomShapeParameterType::NORMAL )
418 aSource.Type = EnhancedCustomShapeParameterType::EQUATION;
419 aSource.Value <<=
static_cast<sal_Int32
>(rEquations.size());
420 rEquations.push_back( aTmpEquation );
423 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
424 aRet.Value <<=
static_cast<sal_Int32
>(rEquations.size());
425 rEquations.push_back( aEquation );
431 aRet.Type = EnhancedCustomShapeParameterType::NORMAL;
438 aEquation.
nPara[ 1 ] = -1;
439 aEquation.
nPara[ 2 ] = 1;
441 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
442 aRet.Value <<=
static_cast<sal_Int32
>(rEquations.size());
443 rEquations.push_back( aEquation );
464 BinaryFunctionExpression(
const ExpressionFunct eFunct, std::shared_ptr<ExpressionNode> xFirstArg, std::shared_ptr<ExpressionNode> xSecondArg ) :
470#if defined(__clang__) || (defined (__GNUC__) && __GNUC__ >= 8)
474 static double getValue(
const ExpressionFunct eFunct,
const std::shared_ptr<ExpressionNode>& rFirstArg,
const std::shared_ptr<ExpressionNode>& rSecondArg )
491 virtual double operator()()
const override
493 return getValue( meFunct, mpFirstArg, mpSecondArg );
495 virtual bool isConstant()
const override
503 virtual EnhancedCustomShapeParameter fillNode( std::vector< EnhancedCustomShapeEquation >& rEquations,
ExpressionNode* , sal_uInt32 nFlags )
override
505 EnhancedCustomShapeParameter aRet;
518 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
519 aRet.Value <<=
static_cast<sal_Int32
>(rEquations.size());
520 rEquations.push_back( aEquation );
528 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
529 aRet.Value <<=
static_cast<sal_Int32
>(rEquations.size());
530 rEquations.push_back( aEquation );
537 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
538 aRet.Value <<=
static_cast<sal_Int32
>(rEquations.size());
539 rEquations.push_back( aSumangle1 );
544 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
545 aRet.Value <<=
static_cast<sal_Int32
>(rEquations.size());
546 rEquations.push_back( aSumangle2 );
550 aEquation.
nPara[ 0 ] = ( rEquations.size() - 2 ) | 0x400;
551 aEquation.
nPara[ 1 ] = ( rEquations.size() - 1 ) | 0x400;
552 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
553 aRet.Value <<=
static_cast<sal_Int32
>(rEquations.size());
554 rEquations.push_back( aEquation );
559 bool bFirstIsEmpty =
mpFirstArg->isConstant() && ( (*mpFirstArg)() == 0 );
560 bool bSecondIsEmpty =
mpSecondArg->isConstant() && ( (*mpSecondArg)() == 0 );
563 aRet =
mpSecondArg->fillNode( rEquations,
nullptr, nFlags );
564 else if ( bSecondIsEmpty )
565 aRet =
mpFirstArg->fillNode( rEquations,
nullptr, nFlags );
572 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
573 aRet.Value <<=
static_cast<sal_Int32
>(rEquations.size());
574 rEquations.push_back( aEquation );
585 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
586 aRet.Value <<=
static_cast<sal_Int32
>(rEquations.size());
587 rEquations.push_back( aEquation );
600 if (
mpFirstArg->isConstant() && (*mpFirstArg)() == 1 )
601 aRet =
mpSecondArg->fillNode( rEquations,
nullptr, nFlags );
602 else if (
mpSecondArg->isConstant() && (*mpSecondArg)() == 1 )
603 aRet =
mpFirstArg->fillNode( rEquations,
nullptr, nFlags );
608 aRet =
mpSecondArg->fillNode( rEquations,
nullptr, nFlags );
614 aRet =
mpFirstArg->fillNode( rEquations,
nullptr, nFlags );
622 aEquation.
nPara[ 2 ] = 1;
623 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
624 aRet.Value <<=
static_cast<sal_Int32
>(rEquations.size());
625 rEquations.push_back( aEquation );
635 aEquation.
nPara[ 1 ] = 1;
637 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
638 aRet.Value <<=
static_cast<sal_Int32
>(rEquations.size());
639 rEquations.push_back( aEquation );
648 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
649 aRet.Value <<=
static_cast<sal_Int32
>(rEquations.size());
650 rEquations.push_back( aEquation );
659 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
660 aRet.Value <<=
static_cast<sal_Int32
>(rEquations.size());
661 rEquations.push_back( aEquation );
670 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
671 aRet.Value <<=
static_cast<sal_Int32
>(rEquations.size());
672 rEquations.push_back( aEquation );
686 std::shared_ptr<ExpressionNode> mpThirdArg;
690 IfExpression( std::shared_ptr<ExpressionNode> xFirstArg,
691 std::shared_ptr<ExpressionNode> xSecondArg,
692 std::shared_ptr<ExpressionNode> xThirdArg ) :
695 mpThirdArg(
std::move( xThirdArg ))
698 virtual bool isConstant()
const override
703 mpThirdArg->isConstant();
705 virtual double operator()()
const override
707 return (*mpFirstArg)() > 0 ? (*mpSecondArg)() : (*mpThirdArg)();
713 virtual EnhancedCustomShapeParameter fillNode( std::vector< EnhancedCustomShapeEquation >& rEquations,
ExpressionNode* , sal_uInt32 nFlags )
override
715 EnhancedCustomShapeParameter aRet;
716 aRet.Type = EnhancedCustomShapeParameterType::EQUATION;
717 aRet.Value <<=
static_cast<sal_Int32
>(rEquations.size());
724 rEquations.push_back( aEquation );
734typedef const char* StringIteratorT;
738 typedef ::std::stack< std::shared_ptr<ExpressionNode> > OperandStack;
751typedef std::shared_ptr< ParserContext > ParserContextSharedPtr;
755class DoubleConstantFunctor
760 explicit DoubleConstantFunctor( ParserContextSharedPtr xContext ) :
764 void operator()(
double n )
const
766 mxContext->maOperandStack.push( std::make_shared<ConstantValueExpression>( n ) );
777 EnumFunctor(
const ExpressionFunct eFunct, ParserContextSharedPtr xContext )
782 void operator()( StringIteratorT rFirst, StringIteratorT rSecond )
const
789 OUString aVal( rFirst + 1, rSecond - rFirst, RTL_TEXTENCODING_UTF8 );
790 mxContext->maOperandStack.push( std::make_shared<AdjustmentExpression>( *
mxContext->mpCustoShape, aVal.toInt32() ) );
795 OUString aVal( rFirst + 1, rSecond - rFirst, RTL_TEXTENCODING_UTF8 );
796 mxContext->maOperandStack.push( std::make_shared<EquationExpression>( *
mxContext->mpCustoShape, aVal.toInt32() ) );
800 mxContext->maOperandStack.push( std::make_shared<EnumValueExpression>( *
mxContext->mpCustoShape, meFunct ) );
805class UnaryFunctionFunctor
812 UnaryFunctionFunctor(
const ExpressionFunct eFunct, ParserContextSharedPtr xContext ) :
817 void operator()( StringIteratorT, StringIteratorT )
const
819 ParserContext::OperandStack& rNodeStack(
mxContext->maOperandStack );
821 if( rNodeStack.empty() )
822 throw ParseError(
"Not enough arguments for unary operator" );
825 std::shared_ptr<ExpressionNode> pArg( std::move(rNodeStack.top()) );
828 if( pArg->isConstant() )
829 rNodeStack.push( std::make_shared<ConstantValueExpression>( UnaryFunctionExpression::getValue( meFunct, pArg ) ) );
831 rNodeStack.push( std::make_shared<UnaryFunctionExpression>( meFunct, pArg ) );
842class BinaryFunctionFunctor
849 BinaryFunctionFunctor(
const ExpressionFunct eFunct, ParserContextSharedPtr xContext ) :
855 void operator()( StringIteratorT, StringIteratorT )
const
857 ParserContext::OperandStack& rNodeStack(
mxContext->maOperandStack );
859 if( rNodeStack.size() < 2 )
860 throw ParseError(
"Not enough arguments for binary operator" );
863 std::shared_ptr<ExpressionNode> pSecondArg( std::move(rNodeStack.top()) );
865 std::shared_ptr<ExpressionNode> pFirstArg( std::move(rNodeStack.top()) );
868 assert(pSecondArg && pFirstArg &&
"count of arg checked before we get here");
871 auto pNode = std::make_shared<BinaryFunctionExpression>( meFunct, pFirstArg, pSecondArg );
873 if( pFirstArg->isConstant() && pSecondArg->isConstant() )
874 rNodeStack.push( std::make_shared<ConstantValueExpression>( (*pNode)() ) );
876 rNodeStack.push( pNode );
886 explicit IfFunctor( ParserContextSharedPtr xContext ) :
890 void operator()( StringIteratorT, StringIteratorT )
const
892 ParserContext::OperandStack& rNodeStack(
mxContext->maOperandStack );
894 if( rNodeStack.size() < 3 )
895 throw ParseError(
"Not enough arguments for ternary operator" );
898 std::shared_ptr<ExpressionNode> pThirdArg( std::move(rNodeStack.top()) );
900 std::shared_ptr<ExpressionNode> pSecondArg( std::move(rNodeStack.top()) );
902 std::shared_ptr<ExpressionNode> pFirstArg( std::move(rNodeStack.top()) );
905 assert(pThirdArg && pSecondArg && pFirstArg);
908 auto pNode = std::make_shared<IfExpression>( pFirstArg, pSecondArg, pThirdArg );
910 if( pFirstArg->isConstant() && pSecondArg->isConstant() && pThirdArg->isConstant() )
911 rNodeStack.push( std::make_shared<ConstantValueExpression>( (*pNode)() ) );
913 rNodeStack.push( pNode );
929template<
typename T >
struct custom_real_parser_policies :
public ::boost::spirit::classic::ureal_parser_policies<T>
931 template<
typename ScannerT >
932 static typename ::boost::spirit::classic::parser_result< ::boost::spirit::classic::chlit<>, ScannerT >::type
933 parse_exp(ScannerT& scan)
936 return ::boost::spirit::classic::ch_p(
'E').parse(scan);
968class ExpressionGrammar :
public ::boost::spirit::classic::grammar< ExpressionGrammar >
976 explicit ExpressionGrammar( ParserContextSharedPtr xParserContext ) :
981 template<
typename ScannerT >
class definition
985 explicit definition(
const ExpressionGrammar& self )
987 using ::boost::spirit::classic::str_p;
988 using ::boost::spirit::classic::range_p;
989 using ::boost::spirit::classic::lexeme_d;
990 using ::boost::spirit::classic::real_parser;
1028 lexeme_d[ +( range_p(
'a',
'z') | range_p(
'A',
'Z') | range_p(
'0',
'9') ) ];
1034 lexeme_d[ +( range_p(
'0',
'9') ) ];
1040 real_parser<double, custom_real_parser_policies<double> >()[ DoubleConstantFunctor(self.getContext()) ]
1047 |
'(' >> additiveExpression >>
')'
1069 BOOST_SPIRIT_DEBUG_RULE(additiveExpression);
1070 BOOST_SPIRIT_DEBUG_RULE(multiplicativeExpression);
1071 BOOST_SPIRIT_DEBUG_RULE(unaryExpression);
1072 BOOST_SPIRIT_DEBUG_RULE(basicExpression);
1073 BOOST_SPIRIT_DEBUG_RULE(unaryFunction);
1074 BOOST_SPIRIT_DEBUG_RULE(binaryFunction);
1075 BOOST_SPIRIT_DEBUG_RULE(ternaryFunction);
1076 BOOST_SPIRIT_DEBUG_RULE(identifier);
1079 const ::boost::spirit::classic::rule< ScannerT >&
start()
const
1093 ::boost::spirit::classic::rule< ScannerT > ternaryFunction;
1094 ::boost::spirit::classic::rule< ScannerT > funcRef_decl;
1095 ::boost::spirit::classic::rule< ScannerT > functionReference;
1096 ::boost::spirit::classic::rule< ScannerT > modRef_decl;
1097 ::boost::spirit::classic::rule< ScannerT > modifierReference;
1098 ::boost::spirit::classic::rule< ScannerT >
identifier;
1101 const ParserContextSharedPtr& getContext()
const
1110const ParserContextSharedPtr& getParserContext()
1112 static ParserContextSharedPtr lcl_parserContext = std::make_shared<ParserContext>();
1116 while( !lcl_parserContext->maOperandStack.empty() )
1117 lcl_parserContext->maOperandStack.pop();
1119 return lcl_parserContext;
1127std::shared_ptr<ExpressionNode>
const & FunctionParser::parseFunction( std::u16string_view rFunction,
const EnhancedCustomShape2d& rCustoShape )
1132 const OString& rAsciiFunction(
1135 StringIteratorT aStart( rAsciiFunction.getStr() );
1136 StringIteratorT aEnd( rAsciiFunction.getStr()+rAsciiFunction.getLength() );
1140 ParserContextSharedPtr pContext = getParserContext();
1141 pContext->mpCustoShape = &rCustoShape;
1143 ExpressionGrammar aExpressionGrammer( pContext );
1144 const ::boost::spirit::classic::parse_info<StringIteratorT> aParseInfo(
1145 ::boost::spirit::classic::parse( aStart,
1147 aExpressionGrammer >> ::boost::spirit::classic::end_p,
1148 ::boost::spirit::classic::space_p ) );
1151 if( !aParseInfo.full )
1152 throw ParseError(
"EnhancedCustomShapeFunctionParser::parseFunction(): string not fully parseable" );
1156 if( pContext->maOperandStack.size() != 1 )
1157 throw ParseError(
"EnhancedCustomShapeFunctionParser::parseFunction(): incomplete or empty expression" );
1160 return pContext->maOperandStack.top();
#define EXPRESSION_FLAG_SUMANGLE_MODE
const ExpressionFunct meFunct
SAL_DLLPRIVATE double GetEnumFunc(const EnhancedCustomShape::ExpressionFunct eVal) const
SAL_DLLPRIVATE double GetAdjustValueAsDouble(const sal_Int32 nIndex) const
SAL_DLLPRIVATE double GetEquationValueAsDouble(const sal_Int32 nIndex) const
virtual css::drawing::EnhancedCustomShapeParameter fillNode(std::vector< EnhancedCustomShapeEquation > &rEquations, ExpressionNode *pOptionalArg, sal_uInt32 nFlags)=0
Operator to retrieve the ms version of expression.
std::shared_ptr< ExpressionNode > mpFirstArg
std::shared_ptr< ExpressionNode > mpSecondArg
#define SAL_INFO(area, stream)
#define DFF_Prop_geoRight
#define DFF_Prop_adjustValue
#define DFF_Prop_geoBottom
SVXCORE_DLLPUBLIC void FillEquationParameter(const css::drawing::EnhancedCustomShapeParameter &, const sal_Int32, EnhancedCustomShapeEquation &)
css::beans::Optional< css::uno::Any > getValue(std::u16string_view id)
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
bool getType(BSTR name, Type &type)
::boost::spirit::classic::rule< ScannerT > unaryExpression
::boost::spirit::classic::rule< ScannerT > additiveExpression
ParserContextSharedPtr mpParserContext
OperandStack maOperandStack
::boost::spirit::classic::rule< ScannerT > binaryFunction
::boost::spirit::classic::rule< ScannerT > multiplicativeExpression
std::shared_ptr< ExpressionNode > mpArg
::boost::spirit::classic::rule< ScannerT > basicExpression
::boost::spirit::classic::rule< ScannerT > identifier
::boost::spirit::classic::rule< ScannerT > unaryFunction
This exception is thrown, when the arithmetic expression parser failed to parse a string.
unsigned _Unwind_Word __attribute__((__mode__(__word__)))