()
| 438 | // Parses a hunk |
| 439 | // This assumes that we are at the start of a hunk. |
| 440 | function parseHunk() { |
| 441 | const chunkHeaderIndex = i, |
| 442 | chunkHeaderLine = diffstr[i++], |
| 443 | chunkHeader = chunkHeaderLine.split(/@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/); |
| 444 | |
| 445 | const hunk = { |
| 446 | oldStart: +chunkHeader[1], |
| 447 | oldLines: typeof chunkHeader[2] === 'undefined' ? 1 : +chunkHeader[2], |
| 448 | newStart: +chunkHeader[3], |
| 449 | newLines: typeof chunkHeader[4] === 'undefined' ? 1 : +chunkHeader[4], |
| 450 | lines: [] as string[] |
| 451 | }; |
| 452 | |
| 453 | // Unified Diff Format quirk: If the chunk size is 0, |
| 454 | // the first number is one lower than one would expect. |
| 455 | // https://www.artima.com/weblogs/viewpost.jsp?thread=164293 |
| 456 | if (hunk.oldLines === 0) { |
| 457 | hunk.oldStart += 1; |
| 458 | } |
| 459 | if (hunk.newLines === 0) { |
| 460 | hunk.newStart += 1; |
| 461 | } |
| 462 | |
| 463 | let addCount = 0, |
| 464 | removeCount = 0; |
| 465 | for ( |
| 466 | ; |
| 467 | i < diffstr.length && (removeCount < hunk.oldLines || addCount < hunk.newLines || diffstr[i]?.startsWith('\\')); |
| 468 | i++ |
| 469 | ) { |
| 470 | const operation = (diffstr[i].length == 0 && i != (diffstr.length - 1)) ? ' ' : diffstr[i][0]; |
| 471 | if (operation === '+' || operation === '-' || operation === ' ' || operation === '\\') { |
| 472 | hunk.lines.push(diffstr[i]); |
| 473 | |
| 474 | if (operation === '+') { |
| 475 | addCount++; |
| 476 | } else if (operation === '-') { |
| 477 | removeCount++; |
| 478 | } else if (operation === ' ') { |
| 479 | addCount++; |
| 480 | removeCount++; |
| 481 | } |
| 482 | } else { |
| 483 | throw new Error(`Hunk at line ${chunkHeaderIndex + 1} contained invalid line ${diffstr[i]}`); |
| 484 | } |
| 485 | } |
| 486 | |
| 487 | // Handle the empty block count case |
| 488 | if (!addCount && hunk.newLines === 1) { |
| 489 | hunk.newLines = 0; |
| 490 | } |
| 491 | if (!removeCount && hunk.oldLines === 1) { |
| 492 | hunk.oldLines = 0; |
| 493 | } |
| 494 | |
| 495 | // Perform sanity checking |
| 496 | if (addCount !== hunk.newLines) { |
| 497 | throw new Error('Added line count did not match for hunk at line ' + (chunkHeaderIndex + 1)); |
no test coverage detected