diff options
Diffstat (limited to 'lib/diff.js')
-rw-r--r-- | lib/diff.js | 233 |
1 files changed, 0 insertions, 233 deletions
diff --git a/lib/diff.js b/lib/diff.js deleted file mode 100644 index 4566623ca..000000000 --- a/lib/diff.js +++ /dev/null @@ -1,233 +0,0 @@ -var fs = require('fs'), - child_process = require('child_process'), - temp = require('temp'), - path = require('path'), - logger = require('./logger').logger, - Promise = require('promise') // jshint ignore:line - ; - -function cleanAndGetIndexes(text) { - var addRules = { - name: "add", - openTag: "{+", - replaceOpenTag: "", - closeTag: "+}", - replaceCloseTag: "" - }; - var delRules = { - name: "del", - openTag: "[-", - replaceOpenTag: "", - closeTag: "-]", - replaceCloseTag: "" - }; - var rules = [addRules, delRules]; - - var TagTypeEnum = { - OPENING: 1, - CLOSING: 2 - }; - - function tagLookup(rules, text, pos) { - var seen = false; - var type = null; - var rule = null; - for (var i = 0; i < rules.length; i++) { - var candidateTag = text.slice(pos, pos + rules[i].openTag.length); - if (rules[i].openTag == candidateTag) { - seen = true; - type = TagTypeEnum.OPENING; - rule = i; - break; - } - candidateTag = text.slice(pos, pos + rules[i].closeTag.length); - if (rules[i].closeTag == candidateTag) { - seen = true; - type = TagTypeEnum.CLOSING; - rule = i; - break; - } - } - - return { - seen: seen, - rule: rule, - type: type - }; - } - - var finalText = ""; - var posInFinalText = 0; // character that is going to be treated - // The position in the original text: - var posInText = 0; // character that is going to be treated - var StateEnum = { - OUTSIDE_TAG: 1, - INSIDE_TAG: 2 - }; - var state = StateEnum.OUTSIDE_TAG; - var zones = [[], []]; - var currentTextBeginPos = 0; - var currentTextEndPos = null; - var currentTagBeginPos = null; - var currentTagEndPos = null; - var currentTag = null; - - function forward() { - posInFinalText = posInFinalText + 1; - posInText = posInText + 1; - } - - function seenOpeningTag() { - memorizeText(); - currentTagBeginPos = posInFinalText; - finalText = finalText.concat(rules[currentTag].replaceOpenTag); - posInFinalText = posInFinalText + rules[currentTag].replaceOpenTag.length; - posInText = posInText + rules[currentTag].openTag.length; - currentTextBeginPos = posInText; - } - - function seenClosingTag() { - memorizeText(); - finalText = finalText.concat(rules[currentTag].replaceCloseTag); - posInFinalText = posInFinalText + rules[currentTag].replaceCloseTag.length; - posInText = posInText + rules[currentTag].closeTag.length; - currentTagEndPos = posInFinalText - 1; - zones[currentTag].push({begin: currentTagBeginPos, end: currentTagEndPos}); - currentTextBeginPos = posInText; - } - - function memorizeText() { - currentTextEndPos = posInText - 1; - if (currentTextEndPos >= currentTextBeginPos) { - finalText = finalText.concat(text.slice(currentTextBeginPos, currentTextEndPos + 1)); - } - } - - function end() { - memorizeText(); - } - - while (posInText < text.length) { - var tag = tagLookup(rules, text, posInText); - if (tag.seen && tag.type == TagTypeEnum.OPENING) { - if (state != StateEnum.OUTSIDE_TAG) { - log.error("Opening tag while not outside tag (tags cannot be nested)"); - return null; - } - currentTag = tag.rule; - seenOpeningTag(); - state = StateEnum.INSIDE_TAG; - } else if (tag.seen && tag.type == TagTypeEnum.CLOSING) { - if (state != StateEnum.INSIDE_TAG) { - log.error("Closing tag while not inside tag."); - return null; - } - if (currentTag != tag.rule) { - log.error("Closing tag, but not of the same type as previously opened."); - return null; - } - seenClosingTag(); - state = StateEnum.OUTSIDE_TAG; - } else { - forward(); - } - } - end(); - - return {text: finalText, zones: zones}; -} - -function newTempDir() { - return new Promise(function (resolve, reject) { - temp.mkdir('compiler-explorer-diff', function (err, dirPath) { - if (err) - reject("Unable to open temp file: " + err); - else - resolve(dirPath); - }); - }); -} - -var writeFile = Promise.denodeify(fs.writeFile); - -function buildDiffHandler(config) { - var maxFileSize = config.maxOutput; - return function diffHandler(req, res) { - var before = req.body.before; - var after = req.body.after; - var error; - if (before === undefined) { - error = 'Warning : Bad request : wrong "before"'; - logger.error(error); - return next(new Error(error)); - } - if (after === undefined) { - error = 'Warning : Bad request : wrong "after"'; - logger.error(error); - return next(new Error(error)); - } - - var tempBeforePath, tempAfterPath; - newTempDir() - .then(function (tmpDir) { - tempBeforePath = path.join(tmpDir, "compiler-explorer-wdiff-before"); - tempAfterPath = path.join(tmpDir, "compiler-explorer-wdiff-after"); - return Promise.all( - writeFile(tempBeforePath, before), - writeFile(tempAfterPath, after) - ); - }) - .then(function () { - var truncated = false; - var stdout = ""; - var child = child_process.spawn(config.wdiffExe, [tempBeforePath, tempAfterPath], - {maxBuffer: maxFileSize, detached: true}); - child.stdout.on('data', function (data) { - if (truncated) return; - if (stdout.length > maxFileSize) { - stdout += "\n[Truncated]"; - truncated = true; - child.kill(); - resolve(stdout); - } - stdout += data; - }); - return new Promise(function (resolve, reject) { - child.on('error', function (e) { - reject(e); - }); - child.on('exit', function () { - // See comment in compile-handler.js - seems needed if the child has immediately exited - setTimeout(function () { - resolve(stdout); - }, 0); - }); - }); - }) - .then(function (output) { - var cleaned = cleanAndGetIndexes(output); - res.set('Content-Type', 'application/json'); - if (cleaned === null) { - res.end(JSON.stringify({ - computedDiff: "Failed to clean the diff", - zones: null - })); - } else { - res.end(JSON.stringify({ - computedDiff: cleaned.text, - zones: cleaned.zones - })); - } - }) - .catch(function (err) { - res.end(JSON.stringify({ - computedDiff: "Failed to diff: " + err, - zones: null - })); - }); - }; -} - -module.exports = { - buildDiffHandler: buildDiffHandler -}; |