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.js153
1 files changed, 125 insertions, 28 deletions
diff --git a/lib/compilers/argument-parsers.js b/lib/compilers/argument-parsers.js
index 4f7535dcd..78f868ef1 100644
--- a/lib/compilers/argument-parsers.js
+++ b/lib/compilers/argument-parsers.js
@@ -27,35 +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-z0-9=+,[\]<>|-]*)\s*(.*)/i;
- let previousOption = false;
-
- utils.eachLine(result.stdout + result.stderr, line => {
- const match = line.match(optionFinder);
- if (!match) {
- if (previousOption && (line.trim().length !== 0)) {
- if (options[previousOption].description.endsWith("-"))
- options[previousOption].description += line.trim();
- else
- options[previousOption].description += " " + line.trim();
- } else {
- previousOption = false;
- }
- return;
- }
- previousOption = match[1];
- options[previousOption] = {
- description: match[2].trim(),
- timesused: 0
- };
- });
+ options = BaseParser.parseLines(result.stdout + result.stderr, optionFinder);
}
- compiler.possibleArguments = options;
+ compiler.possibleArguments.populateOptions(options);
return options;
});
}
@@ -75,11 +93,11 @@ class GCCParser extends BaseParser {
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";
}
@@ -96,11 +114,11 @@ 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";
}
@@ -109,8 +127,87 @@ class ClangParser extends BaseParser {
}
}
+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
};