blob: 5ed68c13a9c1fa9728ac46c2a7d0cd81e20a14a8 [file] [log] [blame] [raw]
Matt Godbolt895bfd52019-05-30 16:33:07 -05001// Copyright (c) 2018, Compiler Explorer Authors
Partouf5c171782018-10-05 16:26:41 +02002// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are met:
6//
7// * Redistributions of source code must retain the above copyright notice,
8// this list of conditions and the following disclaimer.
9// * Redistributions in binary form must reproduce the above copyright
10// notice, this list of conditions and the following disclaimer in the
11// documentation and/or other materials provided with the distribution.
12//
13// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
14// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
17// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
23// POSSIBILITY OF SUCH DAMAGE.
24
Partoufad542bc2018-10-06 14:13:04 +020025const
26 BaseCompiler = require('../base-compiler'),
27 fs = require('fs-extra'),
Partouf42258522018-10-06 23:19:48 +020028 path = require('path'),
29 utils = require('../utils');
Partouf5c171782018-10-05 16:26:41 +020030
31class CleanCompiler extends BaseCompiler {
Partoufd700dfb2018-10-06 23:13:03 +020032 optionsForFilter(filters) {
Partoufad542bc2018-10-06 14:13:04 +020033 if (filters.binary) {
Partouff7c0e752018-10-06 18:09:01 +020034 return [];
Partoufad542bc2018-10-06 14:13:04 +020035 } else {
36 return ['-S'];
37 }
Partouf6a769c12018-10-06 13:58:59 +020038 }
39
Partoufd700dfb2018-10-06 23:13:03 +020040 getOutputFilename(dirPath) {
Partoufad542bc2018-10-06 14:13:04 +020041 return path.join(dirPath, "Clean System Files/example.s");
Partouf6a769c12018-10-06 13:58:59 +020042 }
43
Partoufd700dfb2018-10-06 23:13:03 +020044 preprocessOutput(output) {
Partouf4978fc22018-10-14 02:20:18 +020045 const errorRegex = /^Error \[.*,(\d*),(.*)\]:\s?(.*)/i;
46 const errorLineRegex = /^Error \[.*,(\d*)\]:\s?(.*)/i;
47 const parseerrorRegex = /^Parse error \[.*,(\d*);(\d*),(.*)\]:\s?(.*)/i;
48 const typeeerrorRegex = /^Type error \[.*,(\d*),(.*)\]:\s?(.*)/i;
Partouf42258522018-10-06 23:19:48 +020049 return utils.splitLines(output).map(line => {
Partoufd700dfb2018-10-06 23:13:03 +020050 let matches = line.match(errorRegex);
Partouf49388142018-10-14 02:14:22 +020051 if (!matches) matches = line.match(typeeerrorRegex);
52
53 if (matches) {
54 return "<source>:" + matches[1] + ",0: error: (" + matches[2] + ") " + matches[3];
55 }
56
57 matches = line.match(errorLineRegex);
Partoufd700dfb2018-10-06 23:13:03 +020058 if (matches) {
Partouf8e476082018-10-14 02:04:03 +020059 return "<source>:" + matches[1] + ",0: error: " + matches[2];
Partoufd700dfb2018-10-06 23:13:03 +020060 }
Partouf49388142018-10-14 02:14:22 +020061
62 matches = line.match(parseerrorRegex);
63 if (matches) {
Partouf4978fc22018-10-14 02:20:18 +020064 if (matches[3] === "") {
65 return "<source>:" + matches[1] + "," + matches[2] + ": error: " + matches[4];
66 } else {
67 return "<source>:" + matches[1] + "," + matches[2] + ": error: (" + matches[3] + ") " + matches[4];
68 }
Partouf49388142018-10-14 02:14:22 +020069 }
70
71 return line;
Partouf42258522018-10-06 23:19:48 +020072 }).join("\n");
Partoufad1932f2018-10-06 17:16:39 +020073 }
74
Partouf6a769c12018-10-06 13:58:59 +020075 runCompiler(compiler, options, inputFilename, execOptions) {
Partoufad542bc2018-10-06 14:13:04 +020076 const tmpDir = path.dirname(inputFilename);
Partoufb766e082018-10-06 18:07:11 +020077 const moduleName = path.basename(inputFilename, '.icl');
78 const compilerPath = path.dirname(compiler);
Partoufad542bc2018-10-06 14:13:04 +020079 execOptions = this.getDefaultExecOptions();
80 execOptions.customCwd = tmpDir;
Partoufb766e082018-10-06 18:07:11 +020081 execOptions.env.CLEANLIB = path.join(compilerPath, "../exe");
82 execOptions.env.CLEANPATH = this.compiler.libPath;
Partoufad542bc2018-10-06 14:13:04 +020083 options.pop();
84 options.push(moduleName);
Partouf42258522018-10-06 23:19:48 +020085
86 return this.exec(compiler, options, execOptions).then(result => {
Partoufd700dfb2018-10-06 23:13:03 +020087 return new Promise((resolve) => {
Partouf42258522018-10-06 23:19:48 +020088 result.inputFilename = inputFilename;
89 result.stdout = utils.parseOutput(this.preprocessOutput(result.stdout), inputFilename);
90 result.stderr = utils.parseOutput(this.preprocessOutput(result.stderr), inputFilename);
Partoufb766e082018-10-06 18:07:11 +020091 if (!options.includes("-S")) {
92 const aout = path.join(tmpDir, "a.out");
Partoufd700dfb2018-10-06 23:13:03 +020093 fs.stat(aout).then(() => {
Partoufb766e082018-10-06 18:07:11 +020094 fs.copyFile(aout, this.getOutputFilename(tmpDir)).then(() => {
95 result.code = 0;
96 resolve(result);
97 });
Partoufd700dfb2018-10-06 23:13:03 +020098 }).catch(() => {
Partoufb766e082018-10-06 18:07:11 +020099 result.code = 1;
100 resolve(result);
101 });
102 } else {
Partoufd700dfb2018-10-06 23:13:03 +0200103 fs.stat(this.getOutputFilename(tmpDir)).then(() => {
Partoufb766e082018-10-06 18:07:11 +0200104 result.code = 0;
105 resolve(result);
Partoufd700dfb2018-10-06 23:13:03 +0200106 }).catch(() => {
Partoufb766e082018-10-06 18:07:11 +0200107 resolve(result);
108 });
109 }
110 });
Partoufad542bc2018-10-06 14:13:04 +0200111 });
Partouf5c171782018-10-05 16:26:41 +0200112 }
113}
114
115module.exports = CleanCompiler;