/* Coliru compiler web service JavaScript library. @licstart The following is the entire license notice for the Javascript code in this page. Copyright (C) 2014 Alexander Lamaison The Javascript code in this page is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License (GNU GPL) as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. The code is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU GPL for more details. As additional permission under GNU GPL version 3 section 7, you may distribute non-source (e.g., minimized or compacted) forms of that code without the copy of the GNU GPL normally required by section 4, provided you include this license notice and a URL through which recipients can access the Corresponding Source. @licend The above is the entire license notice for the Javascript code in this page. */ 'use strict'; var coliru = (function() { function displayColiruOutput(codeBlock, compileArea) { // Remove button so the compile-display process can // only happen once compileArea.removeChild(compileArea.firstChild); var sourceCode = codeBlock.textContent; coliru.compile(coliru.makeSourceRunnable(sourceCode), function(response, state) { if (state == 'running') { compileArea.textContent = 'Running...\n'; } else if (state == 'error') { compileArea.textContent = 'Error: ' + reponse; } else { compileArea.textContent = ''; if (response != '') { var outputArea = document.createElement('pre'); compileArea.appendChild(outputArea); outputArea.className += ' coliru-output'; // Pygments output formatting outputArea.className += ' go'; outputArea.textContent = response; } var status = document.createElement('div'); compileArea.appendChild(status); status.className += ' coliru-status'; if (state == 0) { status.textContent = 'Success'; } else { status.textContent = 'Failed (return code ' + state + ')'; } var credit = document.createElement('div'); compileArea.appendChild(credit); credit.className += ' coliru-credit'; credit.innerHTML += [ 'Powered by ', 'Coliru' ].join(''); } // Allow style to change formatting to reflect state compileArea.setAttribute('data-coliru-state', state); }); } function createCompileButton(compileArea, compileAction) { var compileButton = document.createElement('span'); compileButton.textContent = 'Run this code'; compileButton.className += ' runbutton'; compileButton.onclick = compileAction; compileButton.onkeydown = compileAction; compileArea.appendChild(compileButton); } return { compile: function(sourceCode, compileReadyResponse) { var linkOptions = ''; for (var i=0; i < coliru.linkLibraries.length; ++i) { linkOptions += '-l' + coliru.linkLibraries[i] + ' '; } var compileCommand = [ //'g++-4.8 -std=c++11 ', 'clang++ -std=c++11 ', //'clang++ -std=c++11 -stdlib=libc++ -lsupc++ ', '-O2 -Wall -pedantic -pthread ', 'main.cpp ', linkOptions, '&& ./a.out; echo COLIRUSTATUS $?'].join(''); var coliruConnection = new XMLHttpRequest(); coliruConnection.onreadystatechange = function() { if (coliruConnection.readyState == 4) { if (coliruConnection.status != 200) { compileReadyResponse(coliruConnection.response, 'error'); } else { // The command above wil *always* output the last return code // at the end of the command. We extract it and use it as // the status var rawResponse = coliruConnection.response; var pattern = /^([\s\S]*)COLIRUSTATUS (\d+)\n$/m; var splitResponse = rawResponse.match(pattern); compileReadyResponse(splitResponse[1], parseInt(splitResponse[2])); } } else { compileReadyResponse(coliruConnection.response, 'running'); } } coliruConnection.open("POST", "http://coliru.stacked-crooked.com/compile", true); coliruConnection.send( JSON.stringify({ "cmd": compileCommand, "src": sourceCode })); }, linkLibraries: [], magicIncludes: [], makeSourceRunnable: function(sourceCode) { if (coliru.containsMainMethod(sourceCode)) { return sourceCode; } else { var runnableSourceCode = ''; for (var i=0; i < coliru.magicIncludes.length; ++i) { runnableSourceCode += '#include <' + coliru.magicIncludes[i] + '>\n'; } // No return needed (see C++ spec) runnableSourceCode += 'int main() {\n' + sourceCode + '\n}'; return runnableSourceCode; } }, containsMainMethod: function(sourceCode) { return sourceCode.match(/int\s+main\([^\)]*\)\s*[\{;]/); }, // Expects codeBlock to be preceded by a
createCompileArea: function(codeBlock) { var compileArea = document.createElement('div'); // Allow coliru-specific formatting compileArea.className += ' coliru'; // Formatting for coliru before it has run the code compileArea.setAttribute('data-coliru-state', 'not-run'); createCompileButton(compileArea, function(codeBlock, compileArea) { return function() { displayColiruOutput(codeBlock, compileArea); } }(codeBlock, compileArea)); var preCode = codeBlock.parentNode; preCode.parentNode.insertBefore(compileArea, preCode.nextSibling); }, // Onlu update code block inside atag and with // data-lang=c++ attribute updateCodeBlock: function(codeBlock) { if (codeBlock.getAttribute('data-lang') == 'c++' && codeBlock.parentNode.tagName == 'PRE') { coliru.createCompileArea(codeBlock); } }, addRunButtonsToCodeBlocks: function() { var els = document.getElementsByTagName('code'); for (var i = 0; i < els.length; ++i) { coliru.updateCodeBlock(els[i]); } }, } })()