patchFromText function

List<Patch> patchFromText(
  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> patchFromText(String textline) {
  final patches = <Patch>[];
  if (textline.isEmpty) {
    return patches;
  }
  final text = textline.split('\n');
  int textPointer = 0;
  final patchHeader
      = new RegExp('^@@ -(\\d+),?(\\d*) \\+(\\d+),?(\\d*) @@\$');
  while (textPointer < text.length) {
    Match? m = patchHeader.firstMatch(text[textPointer]);
    if (m == null) {
      throw new ArgumentError(
          'Invalid patch string: ${text[textPointer]}');
    }
    final patch = new 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].isEmpty) {
        final sign = text[textPointer][0];
        String line = "";
        try {
          line = Uri.decodeFull(text[textPointer].substring(1));
        } on ArgumentError {
          // Malformed URI sequence.
          throw new ArgumentError(
              'Illegal escape in patch_fromText: $line');
        }
        if (sign == '-') {
          // Deletion.
          patch.diffs.add(new Diff(DIFF_DELETE, line));
        } else if (sign == '+') {
          // Insertion.
          patch.diffs.add(new Diff(DIFF_INSERT, line));
        } else if (sign == ' ') {
          // Minor equality.
          patch.diffs.add(new Diff(DIFF_EQUAL, line));
        } else if (sign == '@') {
          // Start of next patch.
          break;
        } else {
          // WTF?
          throw new ArgumentError(
              'Invalid patch mode "$sign" in: $line');
        }
      }
      textPointer++;
    }
  }
  return patches;
}