aboutsummaryrefslogtreecommitdiffstats
path: root/utils/patch.awk
blob: b651fb25c41a82c3f3473db847aff72adca7eaa7 (plain) (blame)
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
#!/usr/bin/awk -f

# Apply a diff file to an original
# Usage: awk -f patch.awk target-file patch-file

FNR == NR {
    lines[FNR] = $0
    next;
}

{
    patchLines[FNR] = $0
}

END {
    totalPatchLines=length(patchLines)
    totalLines = length(lines)
    patchLineIndex = 1

    mode = "none"

    while (patchLineIndex <= totalPatchLines) {
        line = patchLines[patchLineIndex]

        if (line ~ /^--- / || line ~ /^\+\+\+ /) {
            patchLineIndex++
            continue
        }

        if (line ~ /^@@ /) {
            mode = "hunk"
            hunkIndex++
            patchLineIndex++
            continue
        }

        if (mode == "hunk") {
            while (patchLineIndex <= totalPatchLines && line ~ /^[-+ ]/ && line !~ /^--- /) {
                sanitizedLine = substr(line, 2)
                if (line !~ /^\+/) {
                    hunkTotalOriginalLines[hunkIndex]++;
                    hunkOriginalLines[hunkIndex,hunkTotalOriginalLines[hunkIndex]] = sanitizedLine
                } 
                if (line !~ /^-/) {
                    hunkTotalUpdatedLines[hunkIndex]++;
                    hunkUpdatedLines[hunkIndex,hunkTotalUpdatedLines[hunkIndex]] = sanitizedLine
                }
                patchLineIndex++
                line = patchLines[patchLineIndex]
            }
            mode = "none"
        } else {
            patchLineIndex++
        }
    }

    if (hunkIndex == 0) {
        print "error: no patch" > "/dev/stderr"
        exit 1
    }

    totalHunks = hunkIndex
    hunkIndex = 1

    # inspectHunks()

    for (lineIndex = 1; lineIndex <= totalLines; lineIndex++) {
        line = lines[lineIndex]
        nextLineIndex = 0

        if (line == hunkOriginalLines[hunkIndex,1]) {
            nextLineIndex = lineIndex + 1
            for (i = 2; i <= hunkTotalOriginalLines[hunkIndex]; i++) {
                if (lines[nextLineIndex] != hunkOriginalLines[hunkIndex,i]) {
                    nextLineIndex = 0
                    break
                }
                nextLineIndex++
            }
        }
        if (nextLineIndex > 0) {
            for (i = 1; i <= hunkTotalUpdatedLines[hunkIndex]; i++) {
                print hunkUpdatedLines[hunkIndex,i]
            }
            hunkIndex++
            lineIndex = nextLineIndex -1;
        } else {
            print line
        }
    }

    if (hunkIndex != totalHunks + 1) {
        print "error: unable to apply patch" > "/dev/stderr"
        exit 1
    }
}

function inspectHunks() {
    print "/* Begin inspecting hunks"
    for (i = 1; i <= totalHunks; i++) {
        print ">>>>>> Original"
        for (j = 1; j <= hunkTotalOriginalLines[i]; j++) {
            print hunkOriginalLines[i,j]
        }
        print "======"
        for (j = 1; j <= hunkTotalUpdatedLines[i]; j++) {
            print hunkUpdatedLines[i,j]
        }
        print "<<<<<< Updated"
    }
    print "End inspecting hunks */\n"
}