traverseBlock method

bool traverseBlock(
  1. List<BlockEntry> entries,
  2. int ixStart,
  3. int step,
  4. int ixStop,
  5. Position endPosition,
)

Tests whether the entries matches to the lines at a given start position. Note: this method handles both directions, controlled by entries, ixStart, step and ixStop. entries: the description of the block in the needed order. ixStart: the first index of lines to inspect. step: the offset to get the next line: +1 or -1 ixStop: the first index of lines that should not be inspected endPosition: if the block is found, the end position will be stored here. If step is 1 the end position is end of the block, if step is -1 the start of block is meant. Returns true, if the entries match the lines at the current position.

Implementation

bool traverseBlock(List<BlockEntry> entries, int ixStart, int step,
    int ixStop, Position endPosition) {
  var rc = true;
  var ixEntry = 0;
  var ixLine = ixStart;
  while (rc && ixLine != ixStop) {
    var startColumn = startColumnByIndex(ixLine);
    var line = lineByIndex(ixLine);
    var rc2 = true;
    // Search for the next non optional entry or the first matching optional
    // entry:
    while (ixEntry < entries.length) {
      rc2 = entries[ixEntry].match(line, startColumn);
      if (!rc2) {
        if (!entries[ixEntry].optional) {
          rc = false;
          break;
        } else {
          ixEntry++;
        }
      } else {
        final count =
            entries[ixEntry].countMatchingLines(ixLine, step, ixStop);
        if (count == 0) {
          if (!entries[ixEntry].optional) {
            rc = false;
            break;
          }
        } else {
          ixEntry++;
          ixLine += step * count;
        }
        break;
      }
    }
    if (ixEntry >= entries.length) {
      break;
    }
  }
  if (rc) {
    endPosition.set(ixLine - (step < 0 ? step : 0), 0);
  }
  return rc;
}