| 438 | } |
| 439 | |
| 440 | size_t TExpressionImpl::FindOperation(const TStringBuf& exp, std::array<TStringBuf, MaxOperands>& args, EOperation& oper) { |
| 441 | size_t parenLevel = 0; |
| 442 | size_t condLevel = 0; |
| 443 | size_t condEnd = 0; |
| 444 | size_t numArgs = 0; |
| 445 | oper = O_END; |
| 446 | for (size_t i = exp.size(); i > 0; --i) { |
| 447 | SkipQuoted('"', exp, i); |
| 448 | SkipQuoted('\'', exp, i); |
| 449 | if (exp[i - 1] == ')') { |
| 450 | ++parenLevel; |
| 451 | } else if (exp[i - 1] == '(') { |
| 452 | Y_ENSURE(parenLevel > 0, "TExpression: bad paren balance"); |
| 453 | --parenLevel; |
| 454 | } else if (parenLevel == 0) { |
| 455 | TStringBuf suffix = exp.substr(i - 1); |
| 456 | |
| 457 | if (FastHasPrefix(suffix, ":")) { |
| 458 | ++condLevel; |
| 459 | |
| 460 | if (condLevel == 1) { |
| 461 | condEnd = i - 1; |
| 462 | } |
| 463 | } else if (FastHasPrefix(suffix, "?@")) { |
| 464 | Y_ENSURE(condLevel > 0, "TExpression: bad conditional syntax"); |
| 465 | --condLevel; |
| 466 | |
| 467 | if (condLevel == 0) { |
| 468 | args[0] = exp.substr(0, i - 1); |
| 469 | args[1] = exp.substr(i + 1, condEnd - i - 1); |
| 470 | args[2] = exp.substr(condEnd + 1); |
| 471 | oper = O_STR_COND; |
| 472 | numArgs = 3; |
| 473 | } |
| 474 | } else if (FastHasPrefix(suffix, "?")) { |
| 475 | if (i > 1 && FastHasPrefix(exp.substr(i - 2), ">")) { |
| 476 | continue; |
| 477 | } |
| 478 | |
| 479 | Y_ENSURE(condLevel > 0, "TExpression: bad conditional syntax"); |
| 480 | --condLevel; |
| 481 | |
| 482 | if (condLevel == 0) { |
| 483 | args[0] = exp.substr(0, i - 1); |
| 484 | args[1] = exp.substr(i, condEnd - i); |
| 485 | args[2] = exp.substr(condEnd + 1); |
| 486 | oper = O_COND; |
| 487 | numArgs = 3; |
| 488 | } |
| 489 | } else if (oper != O_COND && oper != O_STR_COND) { |
| 490 | for (EOperation o = O_BINARY_BEGIN; EOperationsPriority[o] < EOperationsPriority[oper]; o = static_cast<EOperation>(o + 1)) { |
| 491 | if (!FastHasPrefix(suffix, EOperationsStrings[o])) { |
| 492 | continue; |
| 493 | } |
| 494 | if (EqualToOneOf(o, O_SUBSTRACT, O_ADD)) { // check if it is unary operations |
| 495 | bool isUnary = false; |
| 496 | for (size_t j = 1; j < i - 1; ++j) { |
| 497 | if (EqualToOneOf(exp[i - 1 - j], ' ', '\n')) { |
nothing calls this directly
no test coverage detected