Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local serialization = require("serialization")
- local unicode = require("unicode")
- local max = math.max
- local function saveFile(data, fl)
- file = io.open(fl, "w")
- file:write(data)
- file:close()
- end
- local function getFileLines(filename)
- local result = {}
- for line in io.lines(filename) do
- table.insert(result, line)
- end
- return result
- end
- function timeOffset()
- local currenttime = os.time()
- local datetime = os.date("!*t", currenttime)
- datetime.isdst = true -- Флаг дневного времени суток
- return currenttime - os.time(datetime)
- end
- local function hunkHeader(arr)
- local header = "@@ -%d,%d +%d,%d @@"
- return string.format(header, arr[1], arr[2], arr[3], arr[4])
- end
- local function longestCommonSubSequence(str1, str2)
- if str1 == nil or str2 == nil then
- return nil
- end
- local str1Len = #str1
- local str2Len = #str2
- local num = {}
- for i = 0, str1Len do
- local subArray = {}
- for j = 0, str2Len do
- subArray[j] = 0
- end
- num[i] = subArray
- end
- for i = 0, str1Len do
- for j = 0, str2Len do
- if str1[i] == str2[j] then
- if i == 0 or j == 0 then
- num[i][j] = 1
- else
- num[i][j] = 1 + num[i - 1][j - 1]
- end
- else
- if i == 0 and j == 0 then
- num[i][j] = 0
- elseif i == 0 and j ~= 0 then
- num[i][j] = max(0, num[i][j - 1])
- elseif i ~= 0 and j == 0 then
- num[i][j] = max(0, num[i - 1][j])
- elseif i ~= 0 and j ~= 0 then
- num[i][j] = max(num[i - 1][j], num[i][j - 1])
- end
- end
- end
- end
- return num
- end
- local function printDiff(arr, str1, str2, i, j)
- local R = {}
- if i > 0 and j > 0 and str1[i] == str2[j] then
- R = printDiff(arr, str1, str2, i - 1, j - 1)
- table.insert(R, {file = "fl", String = " " .. str1[i], line = i})
- return R
- elseif j > 0 and (i == 0 or arr[i][j - 1] >= arr[i - 1][j]) then
- R = printDiff(arr, str1, str2, i, j - 1)
- table.insert(R, {file = "fl2", String = "+" .. str2[j], line = j})
- return R
- elseif i > 0 and (j == 0 or arr[i][j - 1] < arr[i - 1][j]) then
- R = printDiff(arr, str1, str2, i - 1, j)
- table.insert(R, {file = "fl1", String = "-" .. str1[i], line = i})
- return R
- else
- return R
- end
- end
- local function generatePatch(old_file, new_file, patch_file)
- local result = {
- "--- " .. old_file .. "\t" .. os.date("%Y-%m-%d %X") .. "\t" .. "+0" .. math.ceil(timeOffset() / 3600) .. "00",
- "+++ " .. new_file .. "\t" .. os.date("%Y-%m-%d %X") .. "\t" .. "+0" .. math.ceil(timeOffset() / 3600) .. "00"
- }
- local hunks = getHunks(getFileLines(old_file), getFileLines(new_file))
- for i = 1, #hunks do
- table.insert(result, hunkHeader(hunks[i]))
- table.insert(result, table.concat(hunks[i][5], "\r\n"))
- end
- if patch_file:match(".diff") then
- saveFile(table.concat(result, "\r\n"), patch_file)
- else
- saveFile(table.concat(result, "\r\n"), patch_file..".diff")
- end
- end
- function getHunks(old_file_lines, new_file_lines)
- local hunkPositions = {}
- local diffRes =
- printDiff(
- longestCommonSubSequence(old_file_lines, new_file_lines),
- old_file_lines,
- new_file_lines,
- #old_file_lines,
- #new_file_lines
- )
- local isFindStart = false
- local hunkCounter = 0
- local hunkStartPositionInOldFile = 0
- local sequenceCounter = 0
- local addLineCounter = 0
- local delLineCounter = 0
- local hunkAddLineCounter = 0
- local hunkDelLineCounter = 0
- local hunkData = {}
- for k, v in ipairs(diffRes) do
- sequenceCounter = sequenceCounter + 1
- if v["file"] == "fl1" or v["file"] == "fl2" then
- hunkData[#hunkData + 1] = v["String"]
- if v["file"] == "fl1" then
- delLineCounter = delLineCounter + 1
- hunkDelLineCounter = hunkDelLineCounter + 1
- else
- addLineCounter = addLineCounter + 1
- hunkAddLineCounter = hunkAddLineCounter + 1
- end
- if isFindStart == false then
- isFindStart = true
- hunkStartPositionInOldFile = sequenceCounter - (addLineCounter)
- end
- hunkCounter = hunkCounter + 1
- elseif isFindStart then
- hunkPositions[#hunkPositions + 1] = {
- hunkStartPositionInOldFile,
- hunkDelLineCounter,
- sequenceCounter - delLineCounter - 1,
- hunkAddLineCounter,
- hunkData
- }
- hunkCounter = 0
- hunkStartPositionInOldFile = 0
- isFindStart = false
- hunkAddLineCounter = 0
- hunkDelLineCounter = 0
- hunkData = {}
- end
- end
- if isFindStart then
- hunkPositions[#hunkPositions + 1] = {
- hunkStartPositionInOldFile,
- hunkDelLineCounter,
- sequenceCounter - delLineCounter - 1,
- hunkAddLineCounter,
- hunkData
- }
- hunkCounter = 0
- hunkStartPositionInOldFile = 0
- isFindStart = false
- hunkAddLineCounter = 0
- hunkDelLineCounter = 0
- hunkData = {}
- end
- return hunkPositions
- end
- args = require("shell").parse(...)
- generatePatch(args[1], args[2], args[3])
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement