Matt Godbolt | f68198a | 2020-09-26 17:50:40 -0500 | [diff] [blame] | 1 | // Copyright (c) 2017, Compiler Explorer Authors |
Matt Godbolt | 6e7e30b | 2017-12-19 10:15:17 -0600 | [diff] [blame] | 2 | // 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 | |
Austin Morton | 044dcfb | 2020-09-26 16:59:26 -0400 | [diff] [blame] | 25 | import { CompilerArguments } from '../../lib/compiler-arguments'; |
| 26 | import { BaseParser, ClangParser, GCCParser, PascalParser } from '../../lib/compilers/argument-parsers'; |
| 27 | import { FakeCompiler } from '../../lib/compilers/fake-for-test'; |
| 28 | import { makeCompilationEnvironment, should } from '../utils'; |
Matt Godbolt | 6e7e30b | 2017-12-19 10:15:17 -0600 | [diff] [blame] | 29 | |
Rubén | 1a33902 | 2018-06-19 10:09:44 +0200 | [diff] [blame] | 30 | const languages = { |
Rubén Rincón Blanco | ccff4b9 | 2020-08-04 22:39:02 +0200 | [diff] [blame] | 31 | 'c++': {id: 'c++'}, |
Rubén | 1a33902 | 2018-06-19 10:09:44 +0200 | [diff] [blame] | 32 | }; |
| 33 | |
Austin Morton | 1b7fe24 | 2020-02-18 00:03:15 -0500 | [diff] [blame] | 34 | let env; |
Rubén | 1a33902 | 2018-06-19 10:09:44 +0200 | [diff] [blame] | 35 | |
Matt Godbolt | 6e7e30b | 2017-12-19 10:15:17 -0600 | [diff] [blame] | 36 | function makeCompiler(stdout, stderr, code) { |
Austin Morton | 1b7fe24 | 2020-02-18 00:03:15 -0500 | [diff] [blame] | 37 | if (env === undefined) { |
Austin Morton | cadbdf5 | 2020-03-07 01:50:49 -0500 | [diff] [blame] | 38 | env = makeCompilationEnvironment({languages}); |
Austin Morton | 1b7fe24 | 2020-02-18 00:03:15 -0500 | [diff] [blame] | 39 | } |
| 40 | |
Matt Godbolt | 6e7e30b | 2017-12-19 10:15:17 -0600 | [diff] [blame] | 41 | if (code === undefined) code = 0; |
Rubén | 1a33902 | 2018-06-19 10:09:44 +0200 | [diff] [blame] | 42 | const compiler = new FakeCompiler({lang: languages['c++'].id, remote: true}, env); |
Rubén Rincón Blanco | ccff4b9 | 2020-08-04 22:39:02 +0200 | [diff] [blame] | 43 | compiler.exec = () => Promise.resolve({code: code, stdout: stdout || '', stderr: stderr || ''}); |
Austin Morton | bf23550 | 2019-05-29 04:13:44 -0400 | [diff] [blame] | 44 | compiler.execCompilerCached = compiler.exec; |
Rubén Rincón Blanco | ccff4b9 | 2020-08-04 22:39:02 +0200 | [diff] [blame] | 45 | compiler.possibleArguments = new CompilerArguments('g82'); |
partouf | e120290 | 2018-01-03 23:19:25 +0100 | [diff] [blame] | 46 | return compiler; |
partouf | ae1780f | 2018-01-03 22:47:45 +0100 | [diff] [blame] | 47 | } |
| 48 | |
Matt Godbolt | 6e7e30b | 2017-12-19 10:15:17 -0600 | [diff] [blame] | 49 | describe('option parser', () => { |
RabsRincon | 968ce50 | 2018-04-07 17:51:51 +0200 | [diff] [blame] | 50 | it('should do nothing for the base parser', () => { |
| 51 | const compiler = makeCompiler(); |
Austin Morton | 044dcfb | 2020-09-26 16:59:26 -0400 | [diff] [blame] | 52 | return BaseParser.parse(compiler).should.deep.equals(compiler); |
RabsRincon | 968ce50 | 2018-04-07 17:51:51 +0200 | [diff] [blame] | 53 | }); |
Matt Godbolt | 6e7e30b | 2017-12-19 10:15:17 -0600 | [diff] [blame] | 54 | it('should handle empty options', () => { |
Austin Morton | 044dcfb | 2020-09-26 16:59:26 -0400 | [diff] [blame] | 55 | return BaseParser.getOptions(makeCompiler()).should.eventually.deep.equals({}); |
Matt Godbolt | 6e7e30b | 2017-12-19 10:15:17 -0600 | [diff] [blame] | 56 | }); |
| 57 | it('should parse single-dash options', () => { |
Austin Morton | 044dcfb | 2020-09-26 16:59:26 -0400 | [diff] [blame] | 58 | return BaseParser.getOptions(makeCompiler('-foo\n')).should.eventually.deep.equals({ |
Matt Godbolt | 03a3fb3 | 2020-01-14 22:37:58 -0600 | [diff] [blame] | 59 | '-foo': { |
Rubén Rincón Blanco | ccff4b9 | 2020-08-04 22:39:02 +0200 | [diff] [blame] | 60 | description: '', |
| 61 | timesused: 0, |
| 62 | }, |
Matt Godbolt | 03a3fb3 | 2020-01-14 22:37:58 -0600 | [diff] [blame] | 63 | }); |
Matt Godbolt | 6e7e30b | 2017-12-19 10:15:17 -0600 | [diff] [blame] | 64 | }); |
| 65 | it('should parse double-dash options', () => { |
Austin Morton | 044dcfb | 2020-09-26 16:59:26 -0400 | [diff] [blame] | 66 | return BaseParser.getOptions(makeCompiler('--foo\n')).should.eventually.deep.equals({ |
Matt Godbolt | 03a3fb3 | 2020-01-14 22:37:58 -0600 | [diff] [blame] | 67 | '--foo': { |
Rubén Rincón Blanco | ccff4b9 | 2020-08-04 22:39:02 +0200 | [diff] [blame] | 68 | description: '', |
| 69 | timesused: 0, |
| 70 | }, |
Matt Godbolt | 03a3fb3 | 2020-01-14 22:37:58 -0600 | [diff] [blame] | 71 | }); |
Matt Godbolt | 6e7e30b | 2017-12-19 10:15:17 -0600 | [diff] [blame] | 72 | }); |
| 73 | it('should parse stderr options', () => { |
Austin Morton | 044dcfb | 2020-09-26 16:59:26 -0400 | [diff] [blame] | 74 | return BaseParser.getOptions(makeCompiler('', '--bar=monkey\n')).should.eventually.deep.equals({ |
Matt Godbolt | 03a3fb3 | 2020-01-14 22:37:58 -0600 | [diff] [blame] | 75 | '--bar=monkey': { |
Rubén Rincón Blanco | ccff4b9 | 2020-08-04 22:39:02 +0200 | [diff] [blame] | 76 | description: '', |
| 77 | timesused: 0, |
| 78 | }, |
Matt Godbolt | 03a3fb3 | 2020-01-14 22:37:58 -0600 | [diff] [blame] | 79 | }); |
Matt Godbolt | 6e7e30b | 2017-12-19 10:15:17 -0600 | [diff] [blame] | 80 | }); |
| 81 | it('handles non-option text', () => { |
Austin Morton | 044dcfb | 2020-09-26 16:59:26 -0400 | [diff] [blame] | 82 | return BaseParser.getOptions(makeCompiler('-foo=123\nthis is a fish\n-badger=123')).should.eventually.deep.equals( |
Matt Godbolt | 03a3fb3 | 2020-01-14 22:37:58 -0600 | [diff] [blame] | 83 | { |
Rubén Rincón Blanco | ccff4b9 | 2020-08-04 22:39:02 +0200 | [diff] [blame] | 84 | '-foo=123': {description: 'this is a fish', timesused: 0}, |
| 85 | '-badger=123': {description: '', timesused: 0}, |
Matt Godbolt | 03a3fb3 | 2020-01-14 22:37:58 -0600 | [diff] [blame] | 86 | }); |
Matt Godbolt | 6e7e30b | 2017-12-19 10:15:17 -0600 | [diff] [blame] | 87 | }); |
| 88 | it('should ignore if errors occur', () => { |
Austin Morton | 044dcfb | 2020-09-26 16:59:26 -0400 | [diff] [blame] | 89 | return BaseParser.getOptions(makeCompiler('--foo\n', '--bar\n', 1)).should.eventually.deep.equals({}); |
Matt Godbolt | 6e7e30b | 2017-12-19 10:15:17 -0600 | [diff] [blame] | 90 | }); |
| 91 | }); |
| 92 | |
| 93 | describe('gcc parser', () => { |
Austin Morton | 044dcfb | 2020-09-26 16:59:26 -0400 | [diff] [blame] | 94 | it('should handle empty options', async () => { |
| 95 | const result = await GCCParser.parse(makeCompiler()); |
| 96 | should.not.exist(result.compiler.supportsGccDump); |
| 97 | result.compiler.options.should.equals(''); |
Matt Godbolt | 6e7e30b | 2017-12-19 10:15:17 -0600 | [diff] [blame] | 98 | }); |
| 99 | it('should handle options', () => { |
Austin Morton | 044dcfb | 2020-09-26 16:59:26 -0400 | [diff] [blame] | 100 | return GCCParser.parse(makeCompiler('-masm=intel\n-fdiagnostics-color=[blah]\n-fdump-tree-all')) |
Matt Godbolt | 6e7e30b | 2017-12-19 10:15:17 -0600 | [diff] [blame] | 101 | .should.eventually.satisfy(result => { |
partouf | e120290 | 2018-01-03 23:19:25 +0100 | [diff] [blame] | 102 | return Promise.all([ |
| 103 | result.compiler.supportsGccDump.should.equals(true), |
| 104 | result.compiler.supportsIntel.should.equals(true), |
| 105 | result.compiler.intelAsm.should.equals('-masm=intel'), |
Rubén Rincón Blanco | ccff4b9 | 2020-08-04 22:39:02 +0200 | [diff] [blame] | 106 | result.compiler.options.should.equals('-fdiagnostics-color=always'), |
partouf | e120290 | 2018-01-03 23:19:25 +0100 | [diff] [blame] | 107 | ]); |
Matt Godbolt | 6e7e30b | 2017-12-19 10:15:17 -0600 | [diff] [blame] | 108 | }); |
| 109 | }); |
partouf | ae1780f | 2018-01-03 22:47:45 +0100 | [diff] [blame] | 110 | it('should handle undefined options', () => { |
Austin Morton | 044dcfb | 2020-09-26 16:59:26 -0400 | [diff] [blame] | 111 | return GCCParser.parse(makeCompiler('-fdiagnostics-color=[blah]')).should.eventually.satisfy(result => { |
partouf | e120290 | 2018-01-03 23:19:25 +0100 | [diff] [blame] | 112 | return Promise.all([ |
Rubén Rincón Blanco | ccff4b9 | 2020-08-04 22:39:02 +0200 | [diff] [blame] | 113 | result.compiler.options.should.equals('-fdiagnostics-color=always'), |
partouf | e120290 | 2018-01-03 23:19:25 +0100 | [diff] [blame] | 114 | ]); |
partouf | ae1780f | 2018-01-03 22:47:45 +0100 | [diff] [blame] | 115 | }); |
| 116 | }); |
Matt Godbolt | 6e7e30b | 2017-12-19 10:15:17 -0600 | [diff] [blame] | 117 | }); |
| 118 | |
| 119 | describe('clang parser', () => { |
| 120 | it('should handle empty options', () => { |
Austin Morton | 044dcfb | 2020-09-26 16:59:26 -0400 | [diff] [blame] | 121 | return ClangParser.parse(makeCompiler()).should.eventually.satisfy(result => { |
partouf | e120290 | 2018-01-03 23:19:25 +0100 | [diff] [blame] | 122 | return Promise.all([ |
Rubén Rincón Blanco | ccff4b9 | 2020-08-04 22:39:02 +0200 | [diff] [blame] | 123 | result.compiler.options.should.equals(''), |
partouf | e120290 | 2018-01-03 23:19:25 +0100 | [diff] [blame] | 124 | ]); |
Matt Godbolt | 6e7e30b | 2017-12-19 10:15:17 -0600 | [diff] [blame] | 125 | }); |
| 126 | }); |
| 127 | it('should handle options', () => { |
Austin Morton | 044dcfb | 2020-09-26 16:59:26 -0400 | [diff] [blame] | 128 | return ClangParser.parse(makeCompiler('-fno-crash-diagnostics\n-fsave-optimization-record\n-fcolor-diagnostics')) |
Matt Godbolt | 6e7e30b | 2017-12-19 10:15:17 -0600 | [diff] [blame] | 129 | .should.eventually.satisfy(result => { |
partouf | e120290 | 2018-01-03 23:19:25 +0100 | [diff] [blame] | 130 | return Promise.all([ |
| 131 | result.compiler.supportsOptOutput.should.equals(true), |
| 132 | result.compiler.optArg.should.equals('-fsave-optimization-record'), |
asynts | ec21170 | 2019-02-19 21:28:33 +0100 | [diff] [blame] | 133 | |
Rubén Rincón Blanco | ccff4b9 | 2020-08-04 22:39:02 +0200 | [diff] [blame] | 134 | result.compiler.options.should.include('-fcolor-diagnostics'), |
| 135 | result.compiler.options.should.include('-fno-crash-diagnostics'), |
| 136 | result.compiler.options.should.not.include('-fsave-optimization-record'), |
asynts | ec21170 | 2019-02-19 21:28:33 +0100 | [diff] [blame] | 137 | ]); |
| 138 | }); |
| 139 | }); |
Matt Godbolt | 6e7e30b | 2017-12-19 10:15:17 -0600 | [diff] [blame] | 140 | }); |
Partouf | 064ded5 | 2019-01-12 21:42:00 +0100 | [diff] [blame] | 141 | |
Matt Godbolt | 03a3fb3 | 2020-01-14 22:37:58 -0600 | [diff] [blame] | 142 | describe('pascal parser', () => { |
| 143 | it('should handle empty options', () => { |
Austin Morton | 044dcfb | 2020-09-26 16:59:26 -0400 | [diff] [blame] | 144 | return PascalParser.parse(makeCompiler()).should.eventually.satisfy(result => { |
Matt Godbolt | 03a3fb3 | 2020-01-14 22:37:58 -0600 | [diff] [blame] | 145 | return Promise.all([ |
Rubén Rincón Blanco | ccff4b9 | 2020-08-04 22:39:02 +0200 | [diff] [blame] | 146 | result.compiler.options.should.equals(''), |
Matt Godbolt | 03a3fb3 | 2020-01-14 22:37:58 -0600 | [diff] [blame] | 147 | ]); |
| 148 | }); |
| 149 | }); |
| 150 | }); |
| 151 | |
Partouf | 064ded5 | 2019-01-12 21:42:00 +0100 | [diff] [blame] | 152 | describe('popular compiler arguments', () => { |
Austin Morton | 1b7fe24 | 2020-02-18 00:03:15 -0500 | [diff] [blame] | 153 | let compiler; |
| 154 | |
| 155 | before(() => { |
Rubén Rincón Blanco | ccff4b9 | 2020-08-04 22:39:02 +0200 | [diff] [blame] | 156 | compiler = makeCompiler('-fsave-optimization-record\n-x\n-g\n-fcolor-diagnostics\n-O<number> optimization level\n-std=<c++11,c++14,c++17z>'); |
Austin Morton | 1b7fe24 | 2020-02-18 00:03:15 -0500 | [diff] [blame] | 157 | }); |
Partouf | 064ded5 | 2019-01-12 21:42:00 +0100 | [diff] [blame] | 158 | |
| 159 | it('should return 5 arguments', () => { |
Austin Morton | 044dcfb | 2020-09-26 16:59:26 -0400 | [diff] [blame] | 160 | return ClangParser.parse(compiler).then(compiler => { |
Partouf | 064ded5 | 2019-01-12 21:42:00 +0100 | [diff] [blame] | 161 | return compiler.should.satisfy(compiler => { |
| 162 | return Promise.all([ |
| 163 | compiler.possibleArguments.getPopularArguments().should.deep.equal({ |
Rubén Rincón Blanco | ccff4b9 | 2020-08-04 22:39:02 +0200 | [diff] [blame] | 164 | '-O<number>': {description: 'optimization level', timesused: 0}, |
| 165 | '-fcolor-diagnostics': {description: '', timesused: 0}, |
| 166 | '-fsave-optimization-record': {description: '', timesused: 0}, |
| 167 | '-g': {description: '', timesused: 0}, |
| 168 | '-x': {description: '', timesused: 0}, |
| 169 | }), |
Partouf | 064ded5 | 2019-01-12 21:42:00 +0100 | [diff] [blame] | 170 | ]); |
| 171 | }); |
Matt Godbolt | 03a3fb3 | 2020-01-14 22:37:58 -0600 | [diff] [blame] | 172 | }); |
Partouf | 064ded5 | 2019-01-12 21:42:00 +0100 | [diff] [blame] | 173 | }); |
| 174 | |
| 175 | it('should return arguments except the ones excluded', () => { |
Austin Morton | 044dcfb | 2020-09-26 16:59:26 -0400 | [diff] [blame] | 176 | return ClangParser.parse(compiler).then(compiler => { |
Partouf | 064ded5 | 2019-01-12 21:42:00 +0100 | [diff] [blame] | 177 | return compiler.should.satisfy(compiler => { |
| 178 | return Promise.all([ |
Rubén Rincón Blanco | ccff4b9 | 2020-08-04 22:39:02 +0200 | [diff] [blame] | 179 | compiler.possibleArguments.getPopularArguments(['-O3', '--hello']).should.deep.equal({ |
| 180 | '-fcolor-diagnostics': {description: '', timesused: 0}, |
| 181 | '-fsave-optimization-record': {description: '', timesused: 0}, |
| 182 | '-g': {description: '', timesused: 0}, |
| 183 | '-x': {description: '', timesused: 0}, |
| 184 | '-std=<c++11,c++14,c++17z>': {description: '', timesused: 0}, |
| 185 | }), |
Partouf | 064ded5 | 2019-01-12 21:42:00 +0100 | [diff] [blame] | 186 | ]); |
| 187 | }); |
Matt Godbolt | 03a3fb3 | 2020-01-14 22:37:58 -0600 | [diff] [blame] | 188 | }); |
Partouf | 064ded5 | 2019-01-12 21:42:00 +0100 | [diff] [blame] | 189 | }); |
Partouf | 16bae63 | 2019-01-12 22:10:00 +0100 | [diff] [blame] | 190 | |
| 191 | it('should be able to exclude special params with assignments', () => { |
Austin Morton | 044dcfb | 2020-09-26 16:59:26 -0400 | [diff] [blame] | 192 | return ClangParser.parse(compiler).then(compiler => { |
Partouf | 16bae63 | 2019-01-12 22:10:00 +0100 | [diff] [blame] | 193 | return compiler.should.satisfy(compiler => { |
| 194 | return Promise.all([ |
Rubén Rincón Blanco | ccff4b9 | 2020-08-04 22:39:02 +0200 | [diff] [blame] | 195 | compiler.possibleArguments.getPopularArguments(['-std=c++14', '-g', '--hello']).should.deep.equal({ |
| 196 | '-O<number>': {description: 'optimization level', timesused: 0}, |
| 197 | '-fcolor-diagnostics': {description: '', timesused: 0}, |
| 198 | '-fsave-optimization-record': {description: '', timesused: 0}, |
| 199 | '-x': {description: '', timesused: 0}, |
| 200 | }), |
Partouf | 16bae63 | 2019-01-12 22:10:00 +0100 | [diff] [blame] | 201 | ]); |
| 202 | }); |
Matt Godbolt | 03a3fb3 | 2020-01-14 22:37:58 -0600 | [diff] [blame] | 203 | }); |
Partouf | 16bae63 | 2019-01-12 22:10:00 +0100 | [diff] [blame] | 204 | }); |
Partouf | 064ded5 | 2019-01-12 21:42:00 +0100 | [diff] [blame] | 205 | }); |