aboutsummaryrefslogtreecommitdiff
path: root/lib/compilers/argument-parsers.js
diff options
context:
space:
mode:
Diffstat (limited to 'lib/compilers/argument-parsers.js')
-rw-r--r--lib/compilers/argument-parsers.js174
1 files changed, 160 insertions, 14 deletions
diff --git a/lib/compilers/argument-parsers.js b/lib/compilers/argument-parsers.js
index 56b5a40cc..0476ad827 100644
--- a/lib/compilers/argument-parsers.js
+++ b/lib/compilers/argument-parsers.js
@@ -27,18 +27,53 @@ const _ = require('underscore'),
utils = require('../utils');
class BaseParser {
+ static hasSupport(options, forOption) {
+ return _.keys(options).find(option => option.includes(forOption));
+ }
+
+ static parseLines(stdout, optionRegex) {
+ let previousOption = false;
+ let options = {};
+
+ utils.eachLine(stdout, line => {
+ const match = line.match(optionRegex);
+ if (!match) {
+ if (previousOption && (line.trim().length !== 0)) {
+ if (options[previousOption].description.endsWith("-"))
+ options[previousOption].description += line.trim();
+ else {
+ if (options[previousOption].description.length !== 0)
+ options[previousOption].description += " " + line.trim();
+ else
+ options[previousOption].description = line.trim();
+ }
+ } else {
+ previousOption = false;
+ }
+ return;
+ }
+
+ if (match) previousOption = match[1];
+ if (previousOption) {
+ options[previousOption] = {
+ description: match[2].trim(),
+ timesused: 0
+ };
+ }
+ });
+
+ return options;
+ }
+
static getOptions(compiler, helpArg) {
return compiler.exec(compiler.compiler.exe, [helpArg]).then(result => {
- const options = {};
+ let options = {};
if (result.code === 0) {
- const optionFinder = /^\s*(--?[-a-zA-Z]+)/;
+ const optionFinder = /^\s*(--?[a-z0-9=+,[\]<>|-]*)\s*(.*)/i;
- utils.eachLine(result.stdout + result.stderr, line => {
- const match = line.match(optionFinder);
- if (!match) return;
- options[match[1]] = true;
- });
+ options = BaseParser.parseLines(result.stdout + result.stderr, optionFinder);
}
+ compiler.possibleArguments.populateOptions(options);
return options;
});
}
@@ -52,16 +87,17 @@ class GCCParser extends BaseParser {
static parse(compiler) {
return Promise.all([
GCCParser.getOptions(compiler, "--target-help"),
- GCCParser.getOptions(compiler, "--help=common")
+ GCCParser.getOptions(compiler, "--help=common"),
+ GCCParser.getOptions(compiler, "--help=optimizers")
]).then(results => {
const options = _.extend.apply(_.extend, results);
const keys = _.keys(options);
logger.debug("gcc-like compiler options: ", keys.join(" "));
- if (options['-masm']) {
+ if (BaseParser.hasSupport(options, "-masm=")) {
compiler.compiler.intelAsm = "-masm=intel";
compiler.compiler.supportsIntel = true;
}
- if (options['-fdiagnostics-color']) {
+ if (BaseParser.hasSupport(options, "-fdiagnostics-color")) {
if (compiler.compiler.options) compiler.compiler.options += " ";
compiler.compiler.options += "-fdiagnostics-color=always";
}
@@ -78,25 +114,135 @@ class ClangParser extends BaseParser {
static parse(compiler) {
return ClangParser.getOptions(compiler, "--help").then(options => {
logger.debug("clang-like compiler options: ", _.keys(options).join(" "));
- if (options['-fsave-optimization-record']) {
+ if (BaseParser.hasSupport(options, '-fsave-optimization-record')) {
compiler.compiler.optArg = "-fsave-optimization-record";
compiler.compiler.supportsOptOutput = true;
}
- if (options['-fcolor-diagnostics']) {
+ if (BaseParser.hasSupport(options, "-fcolor-diagnostics")) {
if (compiler.compiler.options) compiler.compiler.options += " ";
compiler.compiler.options += "-fcolor-diagnostics";
}
- if (options['-emit-llvm']) {
+ if (BaseParser.hasSupport(options, "-emit-llvm")) {
compiler.compiler.supportsIrView = true;
compiler.compiler.irArg = ['-Xclang', '-emit-llvm', '-fsyntax-only'];
}
+ if (BaseParser.hasSupport(options, "-fno-crash-diagnostics")) {
+ if (compiler.compiler.options) compiler.compiler.options += " ";
+ compiler.compiler.options += "-fno-crash-diagnostics";
+ }
return compiler;
});
}
}
+class PascalParser extends BaseParser {
+ static parse(compiler) {
+ return PascalParser.getOptions(compiler, "-help").then(() => compiler);
+ }
+}
+
+class ISPCParser extends BaseParser {
+ static parse(compiler) {
+ return ISPCParser.getOptions(compiler, "--help").then(() => compiler);
+ }
+
+ static getOptions(compiler, helpArg) {
+ return compiler.exec(compiler.compiler.exe, [helpArg]).then(result => {
+ let options = {};
+ if (result.code === 0) {
+ const optionFinder = /^\s*\[(--?[a-z0-9=+,{}\s[\]<>|-]*)\]\s*(.*)/i;
+
+ options = BaseParser.parseLines(result.stdout + result.stderr, optionFinder);
+ }
+ compiler.possibleArguments.populateOptions(options);
+ return options;
+ });
+ }
+}
+
+class VCParser extends BaseParser {
+ static parse(compiler) {
+ return Promise.all([
+ VCParser.getOptions(compiler, "/help")
+ ]).then(() => {
+ return compiler;
+ });
+ }
+
+ static parseLines(stdout, optionRegex) {
+ let previousOption = false;
+ let options = {};
+
+ const matchLine = (line) => {
+ if (line.startsWith("/?")) return;
+
+ const match = line.match(optionRegex);
+ if (!match) {
+ if (previousOption && (line.trim().length !== 0)) {
+ if (options[previousOption].description.endsWith(":"))
+ options[previousOption].description += " " + line.trim();
+ else {
+ if (options[previousOption].description.length !== 0)
+ options[previousOption].description += ", " + line.trim();
+ else
+ options[previousOption].description = line.trim();
+ }
+ } else {
+ previousOption = false;
+ }
+ return;
+ }
+
+ if (match) previousOption = match[1];
+ if (previousOption) {
+ options[previousOption] = {
+ description: match[2].trim(),
+ timesused: 0
+ };
+ }
+ };
+
+ utils.eachLine(stdout, line => {
+ if (line.length === 0) return;
+ if (line.includes("C/C++ COMPILER OPTIONS")) return;
+ if (line.match(/^\s\s*-.*-$/)) return;
+
+ let col1;
+ let col2;
+ if ((line.length > 39) && (line[40] === '/')) {
+ col1 = line.substr(0, 39);
+ col2 = line.substr(40);
+ } else {
+ col1 = line;
+ col2 = "";
+ }
+
+ if (col1) matchLine(col1);
+ if (col2) matchLine(col2);
+ });
+
+ return options;
+ }
+
+ static getOptions(compiler, helpArg) {
+ return compiler.exec(compiler.compiler.exe, [helpArg]).then(result => {
+ let options = {};
+ if (result.code === 0) {
+ const optionFinder = /^\s*(\/[a-z0-9=:+#.,[\]{}<>|_-]*)\s*(.*)/i;
+
+ options = this.parseLines(result.stdout, optionFinder);
+ }
+ compiler.possibleArguments.populateOptions(options);
+ return options;
+ });
+ }
+}
+
module.exports = {
Base: BaseParser,
Clang: ClangParser,
- GCC: GCCParser
+ GCC: GCCParser,
+ VC: VCParser,
+ Pascal: PascalParser,
+ ISPC: ISPCParser
};