1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: fla.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_filter.hxx"
35 This file include an implementation of FLA - a simple Funtional Language for Attributes.
36 The language is LISP-like and has the following grammar:
37 FLA_Expression ::= '(' FLA_Operation FLA_Attribute+ ')'
38 FLA_Attribtute ::= FLA_Constant | FLA_Expression
39 FLA_Constant ::= '[' String ']'
40 The language currently supports the following operations:
41 "+"-Operation, e.g. (+[1][2]) = [3]
42 "-"-Operation, e.g. (-[3][2]) = [1]
43 "*"-Operation, e.g. (*[3][2]) = [6]
44 "/"-Operation, e.g. (-[6][2]) = [3]
45 "<"-Operation, e.g. (<[3][4]) = [t] resp. (<[4][3]) = []
46 "<="-Operation, e.g. (<=[3][4]) = [t] resp. (<=[4][3]) = []
47 ">"-Operation, e.g. (>[3][4]) = [] resp. (>[4][3]) = [t]
48 ">="-Operation, e.g. (>=[3][4]) = [] resp. (>=[4][3]) = [t]
49 Variable assignment, e.g. ($var1[4])
50 Variable access, e.g. (+($var1[4])($var1)($var1)) = [8]
51 Condition, e.g. (?[t][3][4])=[3] resp. (?[][3][4])=4
52 Priorized Choice, e.g. (|[4][5])=[4] resp. (|[][5])=[5]; i.e. result is the first occurrence of a non-[].
62 sal_Int32
Evaluator::evalFunc(const sal_Unicode
*op
, sal_Int32 opLen
, sal_Int32 args
, sal_Unicode
* argv
[10], sal_Unicode
*result
)
64 if (opLen
==1 && op
[0]==L
'+')
67 for(sal_Int32 i
=0;i
<args
;i
++)
69 double v
=rtl_ustr_toDouble(argv
[i
]);
72 return rtl_ustr_valueOfDouble(result
, res
);
74 else if (opLen
==1 && op
[0]==L
'-' && args
>0)
76 double res
=rtl_ustr_toDouble(argv
[0]);
77 for(sal_Int32 i
=1;i
<args
;i
++)
79 double v
=rtl_ustr_toDouble(argv
[i
]);
82 sal_Int32 _len
= rtl_ustr_valueOfDouble(result
, res
);
85 else if (opLen
==1 && op
[0]==L
'*')
88 for(sal_Int32 i
=0;i
<args
;i
++)
90 double v
=rtl_ustr_toDouble(argv
[i
]);
93 return rtl_ustr_valueOfDouble(result
, res
);
95 else if (opLen
==1 && op
[0]==L
'/' && args
>0)
97 double res
=rtl_ustr_toDouble(argv
[0]);
98 for(sal_Int32 i
=1;i
<args
;i
++)
100 double v
=rtl_ustr_toDouble(argv
[i
]);
103 return rtl_ustr_valueOfDouble(result
, res
);
105 else if (opLen
==1 && op
[0]==L
'>' && args
==2)
107 double p1
=rtl_ustr_toDouble(argv
[0]);
108 double p2
=rtl_ustr_toDouble(argv
[1]);
119 else if (opLen
==1 && op
[0]==L
'<' && args
==2)
121 double p1
=rtl_ustr_toDouble(argv
[0]);
122 double p2
=rtl_ustr_toDouble(argv
[1]);
133 else if (opLen
==2 && op
[0]==L
'<' && op
[1]==L
'=' && args
==2)
135 double p1
=rtl_ustr_toDouble(argv
[0]);
136 double p2
=rtl_ustr_toDouble(argv
[1]);
147 else if (opLen
==2 && op
[0]==L
'>' && op
[1]==L
'=' && args
==2)
149 double p1
=rtl_ustr_toDouble(argv
[0]);
150 double p2
=rtl_ustr_toDouble(argv
[1]);
161 else if (opLen
>1 && op
[0]==L
'$' && args
==0)
163 sal_Int32 reg
=rtl_ustr_toInt32(op
+1, 10);
164 int i
=0; while(i
<99 && environment
[reg
][i
]!=L
'\0') { result
[i
]=environment
[reg
][i
]; i
++; }
168 else if (opLen
>1 && op
[0]==L
'$' && args
==1)
170 sal_Int32 reg
=rtl_ustr_toInt32(op
+1, 10);
171 int i
=0; while(i
<99 && argv
[0]!=NULL
) { result
[i
]=argv
[0][i
]; environment
[reg
][i
]=argv
[0][i
]; i
++; }
172 environment
[reg
][i
]=0; result
[i
]=0;
175 else if (opLen
==1 && op
[0]==L
'?' && args
==3)
178 if (argv
[0][0]==L
'\0')
186 int len
=0; while (*source
!=L
'\0') result
[len
++]=*source
++;
190 else if (opLen
==1 && op
[0]==L
'|' && args
>0)
193 int i
=0; while (i
<args
&& argv
[i
][0]==L
'\0') i
++;
197 int len
=0; while (*source
!=L
'\0') result
[len
++]=*source
++;
207 else if (opLen
==1 && op
[0]==L
'.' && args
>0)
211 for(sal_Int32 i
=0;i
<args
;i
++)
214 while (*source
!=L
'\0') result
[len
++]=*source
++;
219 else if (opLen
==8 && op
[0]=='t' && op
[1]=='w' && op
[2]=='i' && op
[3]=='p' && op
[4]=='s' && op
[5]=='2' && op
[6]=='c' && op
[7]=='m' && args
==1)
221 double v
=rtl_ustr_toDouble(argv
[0]);
222 return rtl_ustr_valueOfDouble(result
, (v
/567.0));
224 else if (opLen
==6 && op
[0]=='s' && op
[1]=='w' && op
[2]=='i' && op
[3]=='t' && op
[4]=='c' && op
[5]=='h' && args
>2)
227 for(int i
=1;i
<args
-1;i
+=2)
229 if (rtl_ustr_compare(argv
[0], argv
[i
])==0)
231 source
=argv
[i
+1]; int len
=0; while (*source
!=L
'\0') result
[len
++]=*source
++;
236 source
=argv
[args
-1]; int len
=0; while (*source
!=L
'\0') result
[len
++]=*source
++;
239 // double v=rtl_ustr_toDouble(argv[0]);
240 // return rtl_ustr_valueOfDouble(result, (v/567.0L));
249 sal_Int32
Evaluator::evalExp(const sal_Unicode
*expr
, sal_Int32 exprLen
, sal_Unicode
*buf
, sal_Int32
*bufLen
)
252 sal_Unicode
* argv
[10];
254 int offset
=0; while(offset
<exprLen
&& expr
[offset
]==' ') offset
++;
255 sal_Int32 startBuf
=*bufLen
;
256 if(expr
[offset
]==L
'(')
259 while(offset
<exprLen
&& expr
[offset
]==' ') offset
++;
261 while(offset
<exprLen
&& expr
[offset
]!=' ' && expr
[offset
]!='[' && expr
[offset
]!='('&& expr
[offset
]!=']' && expr
[offset
]!=')') offset
++;
264 while(offset
<exprLen
&& !done
)
270 argv
[args
++]=buf
+*bufLen
;
271 offset
+=evalExp(expr
+offset
, exprLen
, buf
, bufLen
);
288 sal_Int32 len
=evalFunc(expr
+op
, opLen
, args
, argv
, buf
+startBuf
);
289 *bufLen
=startBuf
+len
;
293 else if(expr
[offset
]==L
'[')
296 argv
[args
++]=buf
+*bufLen
;
297 while (offset
<exprLen
&& (ch
=expr
[offset
++])!=']')
306 const sal_Unicode
*Evaluator::eval(const sal_Unicode
*expr
, sal_Int32 exprLen
)
310 evalExp(expr
, exprLen
, _buf
, &len
);
311 OSL_ASSERT(len
<1024);
318 SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, argv)
321 for(int i=1;i<argc;i++)
323 rtl_uString *param=NULL;
324 rtl_uString_newFromAscii(¶m, argv[i]);
325 ::rtl::OUString _param(param);
326 const sal_Unicode *res=ev.eval(_param.getStr(), _param.getLength());