-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathparse-diff.js
More file actions
119 lines (94 loc) · 2.47 KB
/
parse-diff.js
File metadata and controls
119 lines (94 loc) · 2.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/*
* Parses a [unified diff](http://www.gnu.org/software/diffutils/manual/html_node/Unified-Format.html) into a 1 index list of lines in the 'after' file that were either added or modified
*
* DEBUG help - console.log() inside parseLine and then the counts before/after parsing it is useful
*
* @return { modified: [] }
*/
module.exports = exports = parseDiff;
exports._parseHeaderStr = parseHeaderStr;
function parseDiff(str) {
var pos = 0;
var mappings = {
modified: [],
}
var inHeaderBlock = false;
// drop header
var lineIndex;
try {
var lines = str.split("\n");
for(lineIndex = 0; lineIndex < lines.length; lineIndex++) {
parseLine(lines[lineIndex]);
}
} catch(e) {
throw new Error("parsing failed :" + e.stack + "\n\nline: " + lines[lineIndex] + "\n\nparsed:\n" + lines.slice(0, lineIndex).join("\n") + "\n\nunparsed:\n" + lines.slice(lineIndex).join("\n"));
}
return mappings
function newLine() {
pos += 1;
}
function add() {
markModified();
newLine()
}
function remove() {
}
function markModified() {
mappings.modified.push(pos);
}
function hunk(line) {
var header = parseHeaderStr(line);
pos = header.newer.start;
}
function context() {
newLine();
}
function missingNewline(line) {
if(line !== "\\ No newline at end of file") {
throw new Error("only expecting no newline messages, got: '" + line + "'");
}
}
function stillInHeaderBlock(line) {
var prefix = line.slice(0, 4);
switch(prefix) {
case "new ":
case "dele":
case "inde":
case "--- ":
return true;
case "+++ ":
// end of header
return false;
}
}
function parseLine(line) {
if(line.length === 0) {
return; // EOF
}
if(inHeaderBlock) {
inHeaderBlock = stillInHeaderBlock(line);
return;
}
if(line.slice(0, 7) === "diff --") {
inHeaderBlock = true;
return;
}
switch(line[0]) {
case " ": return context()
case "@": return hunk(line)
case "+": return add()
case "-": return remove()
case "\\": return missingNewline(line)
default: throw new Error("Illegal prefix '" + line[0] + "', for line '" + line + "'")
}
}
}
function parseHeaderStr(header) {
// after start line, lines; before start line, lines - all positions 1 indexed
var match = /^@@ -\d+(?:,\d+)? \+(\d+)(?:,\d+)?/.exec(header)
return {
newer: {
start: parseInt(match[1]),
}
}
}