diff --git a/Operand.cpp b/Operand.cpp index 5302941..3d6f44e 100644 --- a/Operand.cpp +++ b/Operand.cpp @@ -12,9 +12,9 @@ namespace jet { Operand::Operand(coreutils::ZString &in, Tag &tag, bool stop) : in(in), tag(tag) { doubleValue = 0; - + in.skipWhitespace(); - + if(in.startsWith("$[") || in.startsWith("#[")) { string = tag.getVariable(in); doubleValue = string.asDouble(); @@ -38,13 +38,26 @@ namespace jet { Operand parm2(in, tag); if(in.ifNext(")")) { string = parm1.string.substring(parm2.string.asInteger()); - } else if(!in.ifNext(",")) + } else { + // Real, pre-existing bug fixed here: the 3-arg-only branch below + // used to run unconditionally (missing braces around this + // else-if), so even after the 2-arg form above already + // succeeded, it fell through into trying to parse a third + // argument from whatever was left (nothing, since the closing + // ")" was already consumed) - always throwing "operand is not + // valid." right after computing the correct 2-arg result. + // Confirmed via real debug tracing showing an extra Operand + // constructed on empty input immediately after a successful + // 2-arg substring(str, start) call - the 2-arg form was + // completely unusable before this fix. + if(!in.ifNext(",")) throw coreutils::Exception("Expecting , in SUBSTRING expression."); - Operand parm3(in, tag); - if(in.ifNext(")")) { - string = parm1.string.substring(parm2.string.asInteger(), parm3.string.asInteger()); - } else - throw coreutils::Exception("Expecting ) at end of substring expression."); + Operand parm3(in, tag); + if(in.ifNext(")")) { + string = parm1.string.substring(parm2.string.asInteger(), parm3.string.asInteger()); + } else + throw coreutils::Exception("Expecting ) at end of substring expression."); + } } else if(in.ifNextIgnoreCase("LEFT")) { if(!in.ifNext("(")) throw coreutils::Exception("Expecting ( for LEFT parameters."); @@ -405,7 +418,7 @@ namespace jet { } int Operand::parseOperator() { - + if(in.ifNext("!=") || in.ifNext("<>")) { Operand op(in, tag); if(isNumber && op.isNumber) {