patch_fromText method

List<Patch> patch_fromText(
  1. String textline
)

Parse a textual representation of patches and return a List of Patch objects. textline is a text representation of patches. Returns a List of Patch objects. Throws ArgumentError if invalid input.

Implementation

List<Patch> patch_fromText(String textline) {
  final patches = <Patch>[];
  if (textline.isEmpty) {
    return patches;
  }
  final text = textline.split('\n');
  int textPointer = 0;
  final patchHeader =
      RegExp('^@@ -(\\d+),?(\\d*) \\+(\\d+),?(\\d*) @@\$');
  while (textPointer < text.length) {
    var m = patchHeader.firstMatch(text[textPointer]);
    if (m == null) {
      throw ArgumentError('Invalid patch string: ${text[textPointer]}');
    }
    final patch = Patch();
    patches.add(patch);
    patch.start1 = int.parse(m.group(1)!);
    if (m.group(2)!.isEmpty) {
      patch.start1--;
      patch.length1 = 1;
    } else if (m.group(2) == '0') {
      patch.length1 = 0;
    } else {
      patch.start1--;
      patch.length1 = int.parse(m.group(2)!);
    }

    patch.start2 = int.parse(m.group(3)!);
    if (m.group(4)!.isEmpty) {
      patch.start2--;
      patch.length2 = 1;
    } else if (m.group(4) == '0') {
      patch.length2 = 0;
    } else {
      patch.start2--;
      patch.length2 = int.parse(m.group(4)!);
    }
    textPointer++;

    while (textPointer < text.length) {
      if (text[textPointer].isNotEmpty) {
        final sign = text[textPointer][0];
        String? line;
        try {
          line = Uri.decodeFull(text[textPointer].substring(1));
        } on ArgumentError {
          // Malformed URI sequence.
          throw ArgumentError('Illegal escape in patch_fromText: $line');
        }
        if (sign == '-') {
          // Deletion.
          patch.diffs.add(Diff(Operation.delete, line));
        } else if (sign == '+') {
          // Insertion.
          patch.diffs.add(Diff(Operation.insert, line));
        } else if (sign == ' ') {
          // Minor equality.
          patch.diffs.add(Diff(Operation.equal, line));
        } else if (sign == '@') {
          // Start of next patch.
          break;
        } else {
          // WTF?
          throw ArgumentError('Invalid patch mode "$sign" in: $line');
        }
      }
      textPointer++;
    }
  }
  return patches;
}