1
//=============================================================================
3
// File : kvi_kvs_parser_lside.cpp
4
// Creation date : Thu 03 Nov 2003 13.11 CEST by Szymon Stefanek
6
// This file is part of the KVirc irc client distribution
7
// Copyright (C) 2003-2008 Szymon Stefanek (pragma at kvirc dot net)
9
// This program is FREE software. You can redistribute it and/or
10
// modify it under the terms of the GNU General Public License
11
// as published by the Free Software Foundation; either version 2
12
// of the License, or (at your opinion) any later version.
14
// This program is distributed in the HOPE that it will be USEFUL,
15
// but WITHOUT ANY WARRANTY; without even the implied warranty of
16
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17
// See the GNU General Public License for more details.
19
// You should have received a copy of the GNU General Public License
20
// along with this program. If not, write to the Free Software Foundation,
21
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23
//=============================================================================
25
#include "kvi_kvs_parser.h"
26
#include "kvi_kvs_treenode.h"
27
#include "kvi_kvs_report.h"
28
#include "kvi_kvs_kernel.h"
29
#include "kvi_kvs_parser_macros.h"
30
#include "kvi_locale.h"
38
operator,operators,assignment,assign
42
Variable operators , assignments & co.
44
Operator constructs are commands just like the other ones.
45
All the operators work on local or global variables and dictionaries.[br]
46
The generic operator syntax is:[br]
48
[b]<left_operand> <operator> [right_operand][/b][br]
50
where <left_operand> and [right_operand] depend on the <operator>.[br]
51
Some operators have no [right_operand] and these are called [b]unary operators[/b]:
52
they operate directly on <left_operand>.[br]
55
[tr][td]Operator[/td][td]document[/td][/tr]
56
[tr][td]=[/td][td][doc:assignment]assignment operator[/doc][/td][/tr]
57
[tr][td]++[/td][td][doc:incrementdecrement]Increment and decrement operators[/doc][/td][/tr]
58
[tr][td]--[/td][td][doc:incrementdecrement]Increment and decrement operators[/doc][/td][/tr]
59
[tr][td]+=[/td][td][doc:selfarithmetic]Arithmetic self-operators[/doc][/td][/tr]
60
[tr][td]-=[/td][td][doc:selfarithmetic]Arithmetic self-operators[/doc][/td][/tr]
61
[tr][td]*=[/td][td][doc:selfarithmetic]Arithmetic self-operators[/doc][/td][/tr]
62
[tr][td]/=[/td][td][doc:selfarithmetic]Arithmetic self-operators[/doc][/td][/tr]
63
[tr][td]%=[/td][td][doc:selfarithmetic]Arithmetic self-operators[/doc][/td][/tr]
64
[tr][td]|=[/td][td][doc:selfbitwise]Bitwise self-operators[/doc][/td][/tr]
65
[tr][td]&=[/td][td][doc:selfbitwise]Bitwise self-operators[/doc][/td][/tr]
66
[tr][td]^=[/td][td][doc:selfbitwise]Bitwise self-operators[/doc][/td][/tr]
67
[tr][td]<<=[/td][td][doc:selfbitwise]Bitwise self-operators[/doc][/td][/tr]
68
[tr][td]>>=[/td][td][doc:selfbitwise]Bitwise self-operators[/doc][/td][/tr]
69
[tr][td].=[/td][td][doc:stringconcatenation]String concatenation operators[/doc][/td][/tr]
70
[tr][td]<<[/td][td][doc:stringconcatenation]String concatenation operators[/doc][/td][/tr]
71
[tr][td]<,[/td][td][doc:stringconcatenation]String concatenation operators[/doc][/td][/tr]
72
[tr][td]<+[/td][td][doc:arrayconcatenation]Array concatenation[/doc][/td][/tr]
73
[tr][td]=~[/td][td][doc:binding]Binding operator[/doc][/td][/tr]
77
KviKvsTreeNodeData * KviKvsParser::parseOperationRightSide(bool bPreferNumeric)
79
KviPointerList<KviKvsTreeNodeData> * l = new KviPointerList<KviKvsTreeNodeData>();
80
l->setAutoDelete(true);
82
const QChar * pBegin = KVSP_curCharPointer;
86
switch(KVSP_curCharUnicode)
89
goto end_of_the_param;
95
goto end_of_the_param;
100
if(KVSP_curCharIsEndOfCommand)
102
goto end_of_the_param;
104
// separate by single spaces
105
bPreferNumeric = false; // this can't be a number
106
l->append(new KviKvsTreeNodeConstantData(KVSP_curCharPointer,new KviKvsVariant(QString(" "))));
110
// anything else is a parameter
111
KviKvsTreeNodeData * p = parseCommandParameter(bPreferNumeric);
126
// complex parameter needed
127
return new KviKvsTreeNodeCompositeData(pBegin,l);
131
// a single parameter in the list
132
l->setAutoDelete(false);
133
KviKvsTreeNodeData * p = l->first();
137
// empty (this should NEVER happen anyway)
139
return new KviKvsTreeNodeConstantData(pBegin,new KviKvsVariant(QString("")));
157
The assignment is the "plainest" of the operators: it works just like in any other programming language.[br]
160
[b]<target> = <source>[/b]
162
<target> must be a variable, <source> can be any parameter.[br]
163
If the <target> variable doesn't exist, it is created.
164
If it already exists, it is eventually converted to the type of <souce> (scalar, hash or array).[br]
165
If <source> evaluates to an empty value then the <target> variable is unset.
168
[comment]# Assigning a constant to the variable %Tmp[/comment]
171
[comment]# Assigning a string constant to the variable %Tmp[/comment]
174
[comment]# Assigning a string constant to the variable %Tmp[/comment]
175
%Tmp = "some string with whitespace preserved"
177
[comment]# Assigning a variable to another variable copies its contents[/comment]
178
%Someothervariable = "Contents"
179
%Tmp = %Someothervariable
181
[comment]# Assigning a variable string to the variable %z[/comment]
183
%z = my eyes are %color
185
[comment]# Assigning a variable string (with a function call inside) to the variable %x[/comment]
186
%x = the system os is [fnc]$system.osname[/fnc]
188
[comment]# Assigning an empty string to the local variable %y unsets %y[/comment]
191
[comment]# This is equivalent to the above[/comment]
193
[comment]# This is equivalent too, if $function evalutates to an empty string[/comment]
195
[comment]# Assigning a variable string to a hash entry[/comment]
196
%Dict{key} = [fnc]$system.osname[/fnc]\ian
197
[comment]# Unsetting an array entry[/comment]
199
[comment]# Assigning a hash to another: %mydict[] becomes a copy of %anotherdict[][/comment]
200
%anotherdict{"The key"} = "Some dummy value"
201
%mydict = %anotherdict
202
[cmd]echo[/cmd]%mydict{"The key"}
203
[comment]# This will convert %mydict to be a scalar variable (deleting all the %mydict contents!)[/comment]
204
%mydict = "some default value"
205
[comment]# Unsetting a whole hash[/comment]
212
@doc: incrementdecrement
214
Increment and decrement operations
220
Increment and decrement operations
222
These two operators work only on numeric operands.[br]
225
[b]<target>++[/b][br]
226
[b]<target>--[/b][br]
228
++ increments <target> by one, -- decrements <target> by one.[br]
229
These are equivalent to += 1 and -= 1.[br]
230
<target> must be an existing variable and contain an integer value.[br]
231
If <target> contains a real value then the real is truncated to the nearest
232
integer and then incremented or decremented.[br]
236
[cmd]echo[/cmd] "Incrementing"
237
[cmd]while[/cmd](%a < 20)
242
[cmd]echo[/cmd] "Decrementing"
243
[cmd]while[/cmd](%a > 10)
248
[cmd]echo[/cmd] "Testing for loop"
249
[cmd]for[/cmd](%a=0;%a < 10;[b]%a++[/b])
255
[doc:operators]Operators[/doc]
262
Arithmetic self-operators
266
Arithmetic self-operators
268
These operators work only on numeric operands.[br]
271
[b]<target> += <right_operand>[/b][br]
272
[b]<target> -= <right_operand>[/b][br]
273
[b]<target> *= <right_operand>[/b][br]
274
[b]<target> /= <right_operand>[/b][br]
275
[b]<target> %= <right_operand>[/b][br]
277
<target> must be an existing variable and contain a numeric value.
278
<right_operand> must evaluate to a numeric value.
279
Note that if you want <right_operand> to be a result of an expression, you must
280
enclose it in the $(*) expression evaluation call.[br]
281
Operator += sums the <right_operand> value to the <target> value and stores the result in <target>.[br]
282
Operator -= subtracts <right_operand> from <target> and stores the result in <target>.[br]
283
Operator *= multiplies <target> by <right_operand> and stores the result in <target>.[br]
284
Operator /= divides <target> by <right_operand> and stores the result in <target>.[br]
285
Operator %= computes <target> modulus <right_operand> and stores the result in <target>.[br]
286
The division and modulus operators fail with an error if <right_operand> is 0.[br]
287
If both <target> and <right_operand> are integer values then the results of the division
288
and modulus are integers (truncated for the division).[br]
289
If <target> or <right_operand> or both are floating point values then the result is a floating point value.[br]
311
[comment]# nice trick[/comment]
316
[doc:operators]Operators[/doc]
323
Bitwise self-operators
327
Bitwise self-operators
329
These operators work only on integer operands.[br]
332
[b]<target> |= <right_operand>[/b][br]
333
[b]<target> &= <right_operand>[/b][br]
334
[b]<target> ^= <right_operand>[/b][br]
335
[b]<target> >>= <right_operand>[/b][br]
336
[b]<target> <<= <right_operand>[/b][br]
338
<target> must be an existing variable and contain a numeric value.
339
<right_operand> must evaluate to a numeric value.
340
If <target> or <right_operand> are floating point values then they are truncated
341
and converted to integers.[br]
342
Note that if you want <right_operand> to be a result of an expression, you must
343
enclose it in the $(*) expression evaluation call.[br]
344
Operator |= computes <target> bitwise-or <right_operand> and stores the result in <target>.[br]
345
Operator &= computes <target> bitwise-and <right_operand> and stores the result in <target>.[br]
346
Operator ^= computes <target> bitwise-xor <right_operand> and stores the result in <target>.[br]
347
Operator >>= shifts <target> <right_operand> bits to the right and stores the result int <target>.[br]
348
Operator <<= shifts <target> <right_operand> bits to the left and stores the result int <target>.[br]
349
Note that "!=" is not available. You must use %a = $(!%b) to implement it.[br]
350
For operators >>= and <<= <right_operand> must be a positive integer.[br]
367
[doc:operators]Operators[/doc]
372
@doc: stringconcatenation
374
String concatenation operators
378
String concatenation operators
380
These operators concatenate strings.
383
[b]<target> .= <right_operand>[/b][br]
384
[b]<target> << <right_operand>[/b][br]
385
[b]<target> <, <right_operand>[/b][br]
387
Operator .= appends <right_operand> to <target>.
388
Operator << appends a space followed by <right_operand> to <target> if <target> is non empty,
389
otherwise sets <target> to <right_operand>.
390
Operator <, is similar to << but uses a comma to separate the two variable contents.
391
The last two operators are useful in creating space-separated or comma-separated lists.
401
%a <, but linux is better!
405
[doc:operators]Operators[/doc]
410
@doc: arrayconcatenation
412
Array concatenation operator
416
Array concatenation operator
418
This operator concatenates arrays
421
[b]<target> <+ <right_operand>[/b][br]
423
If <target> is not an array, it is converted to one first.
424
After that, if <right_operand> is a scalar then it is appended
425
to the end of the <target> array. If <right_operand> is an array
426
then all of its items are appended to the end of the <target> array.
427
If <right_operand> is a hash then all of its value items
428
are appended to the end of the <target> array.
430
[doc:operators]Operators[/doc]
444
This operator is a really ugly, poor and clueless attempt to reach at least 1% of the
445
power of the perl =~ operator :D[br]
446
It allows some complex string operations to be performed efficently by operating directly
447
on the left operand (in fact this is a lot faster in KVIrc since at least one step of parsing is skipped).[br]
448
Its basic syntax is:[br]
449
[br][b]<left_operand> =~ <operation>[parameters][/b][br][br]
450
Where <operation> may be one of 't','s' and parameters depend on it.[br]
451
<left_operand> is the target of the <operation>.[br]
452
If <left_operand> is an array or dictionary, the <operation> is executed on each item they contain.[br]
453
Operation 't' is the transliteration.[br]
454
The complete syntax with parameters is:[br]
455
[br][b]<left_operand> =~ t/<search characters>/<replacement characters>/[/b][br][br]
456
where <search characters> is a string of characters that are replaced with the corresponding
457
characters in <replacement characters>.[br]
458
This operation can be also named 'y' or 'tr' (to preserve some compatibility with other languages).
460
%A=This is a test string
462
%A=~ tr/abcdefghi/ABCDEFGHI/
465
Operation 's' is the substitution.[br]
466
The complete syntax with parameters is:[br]
467
[br][b]<left_operand> =~ s/<search pattern>/<replacement pattern>/[flags][/b][br][br]
468
where <search pattern> is an extended regular expression to be matched in the <left_operand>
469
and <replacement string> is a special pattern that will replace any occurence found.[br]
470
<search pattern> may contain parentheses to capture parts of the matched text.
471
<replacement string> can contain the escape sequences \\N where N is a number between 1 and 9
472
to be replaced by the captured text.[br]
473
(We use \\N because KVIrc will first unquote the string when parsing...)[br]
474
\\0 is a special escape that will be replaced by the entire match (is always valid!).[br]
475
[flags] may be a combination of the letters 'g','i' and 'w'.[br]
476
'g' causes the search to be global and not stop after the first occurence of <search pattern>.[br]
477
'i' causes the search to be case insensitive.[br]
478
'w' causes the search pattern to be interpreted as a simple wildcard regular expression.
481
%A=This is a test string
483
%A=~ s/([a-z])i([a-z])/\\1I\\2/
485
%A=~ s/([a-z])i([a-z])/\\1@\\2/gi
496
%a <, but linux is better!
500
[doc:operators]Operators[/doc]
503
KviKvsTreeNodeData * KviKvsParser::parseBindingOperationParameter()
505
KviPointerList<KviKvsTreeNodeData> * l = new KviPointerList<KviKvsTreeNodeData>;
506
l->setAutoDelete(true);
508
const QChar * pBegin = KVSP_curCharPointer;
512
switch(KVSP_curCharUnicode)
518
// not a part of a parameter
519
goto end_of_function_parameter;
525
// this may be a data reference
526
KviKvsTreeNodeData * p = parseParameterPercentOrDollar();
539
KviKvsTreeNodeData * p = parseStringParameter();
551
// anything else is a literal
552
l->append(parseBindingOperationLiteralParameter());
557
end_of_function_parameter:
560
// complex parameter needed
561
return new KviKvsTreeNodeCompositeData(pBegin,l);
563
// a single parameter in the list or empty list at all
564
l->setAutoDelete(false);
565
KviKvsTreeNodeData * p = l->first();
567
if(!p)p = new KviKvsTreeNodeConstantData(KVSP_curCharPointer,new KviKvsVariant(QString("")));
576
KviKvsTreeNodeOperation * KviKvsParser::parseBindingOperation()
580
const QChar * pBegin = KVSP_curCharPointer;
582
while(KVSP_curCharIsLetter)KVSP_skipChar;
584
QString szOp = QString(pBegin,KVSP_curCharPointer - pBegin).toLower();
588
if(KVSP_curCharUnicode != '/')
590
error(KVSP_curCharPointer,__tr2qs_ctx("Found character '%q' (unicode %x) where a slash '/' was expected","kvs"),KVSP_curCharPointer,KVSP_curCharUnicode);
596
KviKvsTreeNodeData * pFirst = parseBindingOperationParameter();
599
if(KVSP_curCharIsEndOfCommand)
601
error(KVSP_curCharPointer,__tr2qs_ctx("Unexpected end of command in binding operation, at least two slashes are missing","kvs"));
606
if(KVSP_curCharUnicode != '/')
608
error(KVSP_curCharPointer,__tr2qs_ctx("Found character '%q' (unicode %x) where a slash '/' was expected","kvs"),KVSP_curCharPointer,KVSP_curCharUnicode);
615
KviKvsTreeNodeData * pSecond = parseBindingOperationParameter();
622
if(KVSP_curCharIsEndOfCommand)
624
error(KVSP_curCharPointer,__tr2qs_ctx("Unexpected end of command in binding operation, at least one slash is missing","kvs"));
629
if(KVSP_curCharUnicode != '/')
631
error(KVSP_curCharPointer,__tr2qs_ctx("Found character '%q' (unicode %x) where a slash '/' was expected","kvs"),KVSP_curCharPointer,KVSP_curCharUnicode);
638
KviKvsTreeNodeData * pThird = parseCommandParameter();
648
pThird = new KviKvsTreeNodeConstantData(KVSP_curCharPointer,new KviKvsVariant(QString("")));
651
while(!KVSP_curCharIsEndOfCommand)KVSP_skipChar;
652
if(!KVSP_curCharIsEndOfBuffer)KVSP_skipChar;
654
if((szOp == "t") || (szOp == "tr") || (szOp == "y"))
656
// transliteration tr/szFirst/szSecond/szFlags
657
return new KviKvsTreeNodeOperationStringTransliteration(pBegin,pFirst,pSecond,pThird);
658
} else if(szOp == "s")
660
// regexp substitution s/szFirst/szSecond/szFlags
661
return new KviKvsTreeNodeOperationStringSubstitution(pBegin,pFirst,pSecond,pThird);
664
error(KVSP_curCharPointer,__tr2qs_ctx("Unknown binding operation '%Q'","kvs"),&szOp);
669
KviKvsTreeNodeOperation * KviKvsParser::parseOperation()
672
const QChar * pBegin = KVSP_curCharPointer;
674
switch(KVSP_curCharUnicode)
679
if(KVSP_curCharUnicode == '~')
683
if(KVSP_curCharIsEndOfCommand)
685
error(KVSP_curCharPointer,__tr2qs_ctx("Missing right side operand for the binding operator '=~'","kvs"));
688
return parseBindingOperation();
691
KviKvsTreeNodeData * d = parseOperationRightSide(true);
692
if(!d)return 0; // error
693
return new KviKvsTreeNodeOperationAssignment(pBegin,d);
699
switch(KVSP_curCharUnicode)
705
if(!KVSP_curCharIsEndOfCommand)
707
warning(KVSP_curCharPointer,__tr2qs_ctx("Trailing garbage ignored after operator '++'","kvs"));
709
while(!KVSP_curCharIsEndOfCommand)KVSP_skipChar;
710
if(!KVSP_curCharIsEndOfBuffer)KVSP_skipChar;
711
return new KviKvsTreeNodeOperationIncrement(pBegin);
717
if(KVSP_curCharIsEndOfCommand)
719
error(KVSP_curCharPointer,__tr2qs_ctx("Missing right operand for operator '+='","kvs"));
722
KviKvsTreeNodeData * d = parseOperationRightSide(true);
723
if(!d)return 0; // error
724
return new KviKvsTreeNodeOperationSelfSum(pBegin,d);
730
switch(KVSP_curCharUnicode)
736
if(!KVSP_curCharIsEndOfCommand)
738
warning(KVSP_curCharPointer,__tr2qs_ctx("Trailing garbage ignored after operator '--'","kvs"));
740
while(!KVSP_curCharIsEndOfCommand)KVSP_skipChar;
741
if(!KVSP_curCharIsEndOfBuffer)KVSP_skipChar;
742
return new KviKvsTreeNodeOperationDecrement(pBegin);
745
warning(KVSP_curCharPointer,__tr2qs_ctx("This looks a lot like an object handle dereferencing operator '->' but in fact it isn't. Maybe you forgot a '$' just after?","kvs"));
751
if(KVSP_curCharIsEndOfCommand)
753
error(KVSP_curCharPointer,__tr2qs_ctx("Missing right operand for operator '-='","kvs"));
756
KviKvsTreeNodeData * d = parseOperationRightSide(true);
757
if(!d)return 0; // error
758
return new KviKvsTreeNodeOperationSelfSubtraction(pBegin,d);
764
switch(KVSP_curCharUnicode)
768
if(KVSP_curCharUnicode == '=')
772
if(KVSP_curCharIsEndOfCommand)
774
error(KVSP_curCharPointer,__tr2qs_ctx("Missing right operand for operator '<<='","kvs"));
777
KviKvsTreeNodeData * d = parseOperationRightSide(true);
778
if(!d)return 0; // error
779
return new KviKvsTreeNodeOperationSelfShl(pBegin,d);
782
if(KVSP_curCharIsEndOfCommand)
784
error(KVSP_curCharPointer,__tr2qs_ctx("Missing right operand for operator '<<'","kvs"));
787
KviKvsTreeNodeData * d = parseOperationRightSide();
788
if(!d)return 0; // error
789
return new KviKvsTreeNodeOperationStringAppendWithSpace(pBegin,d);
796
if(KVSP_curCharIsEndOfCommand)
798
error(KVSP_curCharPointer,__tr2qs_ctx("Missing right operand for operator '<,'","kvs"));
801
KviKvsTreeNodeData * d = parseOperationRightSide();
802
if(!d)return 0; // error
803
return new KviKvsTreeNodeOperationStringAppendWithComma(pBegin,d);
810
if(KVSP_curCharIsEndOfCommand)
812
error(KVSP_curCharPointer,__tr2qs_ctx("Missing right operand for operator '<+'","kvs"));
815
KviKvsTreeNodeData * d = parseOperationRightSide();
816
if(!d)return 0; // error
817
return new KviKvsTreeNodeOperationArrayAppend(pBegin,d);
824
switch(KVSP_curCharUnicode)
828
if(KVSP_curCharUnicode == '=')
832
if(KVSP_curCharIsEndOfCommand)
834
error(KVSP_curCharPointer,__tr2qs_ctx("Missing right operand for operator '>>='","kvs"));
837
KviKvsTreeNodeData * d = parseOperationRightSide(true);
838
if(!d)return 0; // error
839
return new KviKvsTreeNodeOperationSelfShr(pBegin,d);
846
switch(KVSP_curCharUnicode)
851
if(KVSP_curCharIsEndOfCommand)
853
error(KVSP_curCharPointer,__tr2qs_ctx("Missing right operand for operator '.='","kvs"));
856
KviKvsTreeNodeData * d = parseOperationRightSide();
857
if(!d)return 0; // error
858
return new KviKvsTreeNodeOperationStringAppend(pBegin,d);
862
#define SELF_OPERATOR(__opchar,__opstr,__class) \
865
switch(KVSP_curCharUnicode) \
870
if(KVSP_curCharIsEndOfCommand) \
872
error(KVSP_curCharPointer,__tr2qs_ctx("Missing right operand for operator '" __opstr "='","kvs")); \
875
KviKvsTreeNodeData * d = parseOperationRightSide(true); \
877
return new __class(pBegin,d); \
881
SELF_OPERATOR('*',"*",KviKvsTreeNodeOperationSelfMultiplication)
882
SELF_OPERATOR('/',"/",KviKvsTreeNodeOperationSelfDivision)
883
SELF_OPERATOR('%',"%",KviKvsTreeNodeOperationSelfModulus)
884
SELF_OPERATOR('|',"|",KviKvsTreeNodeOperationSelfOr)
885
SELF_OPERATOR('&',"&",KviKvsTreeNodeOperationSelfAnd)
886
SELF_OPERATOR('^',"^",KviKvsTreeNodeOperationSelfXor)
889
error(pBegin,__tr2qs_ctx("Unknown operator","kvs"));
893
KviKvsTreeNodeInstruction * KviKvsParser::parseVoidFunctionCallOrOperation()
895
KVSP_ASSERT((KVSP_curCharUnicode == '$') || (KVSP_curCharUnicode == '%') || (KVSP_curCharUnicode == '@'));
897
const QChar * pBegin = KVSP_curCharPointer;
899
KviKvsTreeNodeData * r = parsePercentOrDollar();
909
if(KVSP_curCharIsEndOfCommand)
911
// the end of the command
912
if(!r->isFunctionCall())
916
warning(pBegin,__tr2qs_ctx("Unexpected (and senseless) read-only data evaluation","kvs"));
917
error(KVSP_curCharPointer,__tr2qs_ctx("Syntax error: confused by earlier errors: bailing out","kvs"));
919
error(KVSP_curCharPointer,__tr2qs_ctx("Unexpected end of script after a variable reference: expected operator","kvs"));
924
if(!KVSP_curCharIsEndOfBuffer)KVSP_skipChar;
925
return new KviKvsTreeNodeVoidFunctionCall(r->location(),(KviKvsTreeNodeFunctionCall *)r);
929
// not the end of a command : an operation
932
// must be followed by the end of a command
933
if(r->isFunctionCall())
935
error(KVSP_curCharPointer,__tr2qs_ctx("Unexpected character '%q' (unicode %x) after a void function call: end of instruction expected","kvs"),KVSP_curCharPointer,KVSP_curCharUnicode);
937
warning(pBegin,__tr2qs_ctx("Unexpected (and senseless) read-only data evaluation","kvs"));
938
warning(pBegin,__tr2qs_ctx("Unexpected character '%q' (unicode %x)","kvs"),KVSP_curCharPointer,KVSP_curCharUnicode);
939
error(KVSP_curCharPointer,__tr2qs_ctx("Syntax error: confused by earlier errors: bailing out","kvs"));
945
// ok.. parse the operation
946
KviKvsTreeNodeOperation * op = parseOperation();
953
op->setTargetVariableReference(r);