Config file: Treat section names as target triple regexps (#2718)

This commit is contained in:
Martin Kinkelin 2018-06-01 20:42:01 +02:00 committed by GitHub
parent 7816e7730a
commit ddbd77c009
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 109 additions and 72 deletions

View file

@ -232,7 +232,7 @@ after_test:
ren lib lib32
(cat etc\ldc2.conf).replace('%%ldcbinarypath%%/../lib', '%%ldcbinarypath%%/../lib64') | Set-Content etc\ldc2.conf
$conf32 = cat ..\ldc2-x86\etc\ldc2.conf -Raw
$conf32 = "`r`ni686-pc-windows-msvc:" + $conf32.Substring($conf32.IndexOf("`r`ndefault:") + 10)
$conf32 = "`r`n""i[3-6]86-.*-windows-msvc"":" + $conf32.Substring($conf32.IndexOf("`r`ndefault:") + 10)
$conf32 = $conf32.Replace('%%ldcbinarypath%%/../lib', '%%ldcbinarypath%%/../lib32')
Add-Content etc\ldc2.conf $conf32
cd ..

View file

@ -136,7 +136,7 @@ EBNF grammar.
It is a subset of the libconfig grammar (http://www.hyperrealm.com/libconfig).
config = { ows , setting } , ows ;
setting = name , (":" | "=") , value , [";" | ","] ;
setting = (name | string) , (":" | "=") , value , [";" | ","] ;
name = alpha , { alpha | digit | "_" | "-" } ;
value = string | array | group ;
array = "[" , ows ,
@ -445,14 +445,20 @@ struct Parser
Setting parseSetting()
{
immutable name = accept(Token.name);
string name;
auto t = getTok(name);
if (t != Token.name && t != Token.str)
{
unexpectedTokenError(t, Token.name, name);
assert(false);
}
accept(Token.assign);
Setting res = parseValue(name);
string s;
immutable t = getTok(s);
t = getTok(s);
if (t != Token.semicolon && t != Token.comma)
{
ungetTok(t, s);
@ -567,25 +573,25 @@ unittest
`// comment
// comment
group-1: {};
group-1_2: {};
// comment
Group-2:
"86(_64)?-.*linux\\.?":
{
// comment
scalar = "abc";
// comment
Array_1 = [ "a" ];
Array_1-2 = [ "a" ];
};
`;
auto settings = Parser(input).parseConfig();
assert(settings.length == 2);
assert(settings[0].name == "group-1");
assert(settings[0].name == "group-1_2");
assert(settings[0].type == Setting.Type.group);
assert((cast(GroupSetting) settings[0]).children == []);
assert(settings[1].name == "Group-2");
assert(settings[1].name == "86(_64)?-.*linux\\.?");
assert(settings[1].type == Setting.Type.group);
auto group2 = cast(GroupSetting) settings[1];
assert(group2.children.length == 2);
@ -594,7 +600,7 @@ Group-2:
assert(group2.children[0].type == Setting.Type.scalar);
assert((cast(ScalarSetting) group2.children[0]).val == "abc");
assert(group2.children[1].name == "Array_1");
assert(group2.children[1].name == "Array_1-2");
assert(group2.children[1].type == Setting.Type.array);
assert((cast(ArraySetting) group2.children[1]).vals == [ "a" ]);
}

View file

@ -13,6 +13,7 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Regex.h"
#include <cassert>
#include <cstring>
#include <iostream>
@ -172,7 +173,7 @@ bool ConfigFile::locate(std::string &pathstr) {
return false;
}
bool ConfigFile::read(const char *explicitConfFile, const char *section) {
bool ConfigFile::read(const char *explicitConfFile, const char *triple) {
std::string pathstr;
// explicitly provided by user in command line?
if (explicitConfFile) {
@ -201,7 +202,7 @@ bool ConfigFile::read(const char *explicitConfFile, const char *section) {
pathcstr = strdup(pathstr.c_str());
auto binpath = exe_path::getBinDir();
return readConfig(pathcstr, section, binpath.c_str());
return readConfig(pathcstr, triple, binpath.c_str());
}
void ConfigFile::extendCommandLine(llvm::SmallVectorImpl<const char *> &args) {
@ -219,3 +220,7 @@ void ConfigFile::extendCommandLine(llvm::SmallVectorImpl<const char *> &args) {
args.insert(runIndex == 0 ? args.end() : args.begin() + runIndex,
postSwitches.begin(), postSwitches.end());
}
bool ConfigFile::sectionMatches(const char *section, const char *triple) {
return llvm::Regex(section).match(triple);
}

View file

@ -29,27 +29,28 @@ string prepareBinDir(const(char)* binDir)
return cast(string)res; // assumeUnique
}
ArraySetting findArraySetting(GroupSetting section, string name)
T findSetting(T)(GroupSetting[] sections, Setting.Type type, string name)
{
// lexically later sections dominate earlier ones
foreach_reverse (section; sections)
{
if (!section) return null;
foreach (c; section.children)
{
if (c.type == Setting.Type.array && c.name == name)
return cast(ArraySetting) c;
if (c.type == type && c.name == name)
return cast(T) c;
}
}
return null;
}
ScalarSetting findScalarSetting(GroupSetting section, string name)
ArraySetting findArraySetting(GroupSetting[] sections, string name)
{
if (!section) return null;
foreach (c; section.children)
{
if (c.type == Setting.Type.scalar && c.name == name)
return cast(ScalarSetting) c;
return findSetting!ArraySetting(sections, Setting.Type.array, name);
}
return null;
ScalarSetting findScalarSetting(GroupSetting[] sections, string name)
{
return findSetting!ScalarSetting(sections, Setting.Type.scalar, name);
}
string replace(string str, string pattern, string replacement)
@ -107,47 +108,37 @@ private:
Array!(const(char)*) postSwitches;
const(char)* rpathcstr;
bool readConfig(const(char)* cfPath, const(char)* sectionName, const(char)* binDir)
static bool sectionMatches(const(char)* section, const(char)* triple);
bool readConfig(const(char)* cfPath, const(char)* triple, const(char)* binDir)
{
switches.setDim(0);
postSwitches.setDim(0);
immutable dBinDir = prepareBinDir(binDir);
const dSec = sectionName[0 .. strlen(sectionName)];
try
{
GroupSetting section, defaultSection;
GroupSetting[] sections; // in lexical order
foreach (s; parseConfigFile(cfPath))
{
if (s.type != Setting.Type.group)
continue;
if (s.name == dSec)
section = cast(GroupSetting) s;
else if (s.name == "default")
defaultSection = cast(GroupSetting) s;
if (s.type == Setting.Type.group &&
(s.name == "default" || sectionMatches((s.name ~ '\0').ptr, triple)))
{
sections ~= cast(GroupSetting) s;
}
}
if (!section && !defaultSection)
if (sections.length == 0)
{
const dTriple = triple[0 .. strlen(triple)];
const dCfPath = cfPath[0 .. strlen(cfPath)];
if (sectionName)
throw new Exception("Could not look up section '" ~ cast(string) dSec
~ "' nor the 'default' section in " ~ cast(string) dCfPath);
else
throw new Exception("Could not look up 'default' section in " ~ cast(string) dCfPath);
throw new Exception("No matching section for triple '" ~ cast(string) dTriple
~ "' in " ~ cast(string) dCfPath);
}
ArraySetting findArray(string name)
{
auto r = findArraySetting(section, name);
if (!r)
r = findArraySetting(defaultSection, name);
return r;
}
auto switches = findArray("switches");
auto postSwitches = findArray("post-switches");
auto switches = findArraySetting(sections, "switches");
auto postSwitches = findArraySetting(sections, "post-switches");
if (!switches && !postSwitches)
{
const dCfPath = cfPath[0 .. strlen(cfPath)];
@ -170,16 +161,7 @@ private:
applyArray(this.switches, switches);
applyArray(this.postSwitches, postSwitches);
ScalarSetting findScalar(string name)
{
auto r = findScalarSetting(section, name);
if (!r)
r = findScalarSetting(defaultSection, name);
return r;
}
auto rpath = findScalar("rpath");
if (rpath)
if (auto rpath = findScalarSetting(sections, "rpath"))
this.rpathcstr = (rpath.val.replace("%%ldcbinarypath%%", dBinDir) ~ '\0').ptr;
return true;
@ -191,3 +173,10 @@ private:
}
}
}
unittest
{
assert(ConfigFile.sectionMatches("i[3-6]86-.*-windows-msvc", "i686-pc-windows-msvc"));
assert(ConfigFile.sectionMatches("86(_64)?-.*-linux", "x86_64--linux-gnu"));
assert(!ConfigFile.sectionMatches("^linux", "x86_64--linux-gnu"));
}

View file

@ -24,7 +24,7 @@ class ConfigFile {
public:
static ConfigFile instance;
bool read(const char *explicitConfFile, const char *section);
bool read(const char *explicitConfFile, const char *triple);
llvm::StringRef path() {
return pathcstr ? llvm::StringRef(pathcstr) : llvm::StringRef();
@ -38,9 +38,10 @@ public:
private:
bool locate(std::string &pathstr);
static bool sectionMatches(const char *section, const char *triple);
// implemented in D
bool readConfig(const char *cfPath, const char *section, const char *binDir);
bool readConfig(const char *cfPath, const char *triple, const char *binDir);
const char *pathcstr = nullptr;
Array<const char *> switches;

View file

@ -1,7 +1,19 @@
// See comments in driver/config.d in ldc source tree for grammar description of
// this config file.
// The default group is required
// For cross-compilation, you can add sections for specific target triples by
// naming the sections as (quoted) regex patterns. See LDC's `-v` output
// (`config` line) to figure out your normalized triple, depending on the used
// `-mtriple`, `-m32` etc. E.g.:
//
// "^arm.*-linux-gnueabihf$": { … };
// "86(_64)?-.*-linux": { … };
// "i[3-6]86-.*-windows-msvc": { … };
//
// Later sections take precedence and override settings from previous matching
// sections while inheriting unspecified settings from previous sections.
// A `default` section always matches (treated as ".*") and is therefore usually
// the first section.
default:
{
// default switches injected before all explicit command-line switches

View file

@ -1,7 +1,19 @@
// See comments in driver/config.d in ldc source tree for grammar description of
// this config file.
// The default group is required
// For cross-compilation, you can add sections for specific target triples by
// naming the sections as (quoted) regex patterns. See LDC's `-v` output
// (`config` line) to figure out your normalized triple, depending on the used
// `-mtriple`, `-m32` etc. E.g.:
//
// "^arm.*-linux-gnueabihf$": { … };
// "86(_64)?-.*-linux": { … };
// "i[3-6]86-.*-windows-msvc": { … };
//
// Later sections take precedence and override settings from previous matching
// sections while inheriting unspecified settings from previous sections.
// A `default` section always matches (treated as ".*") and is therefore usually
// the first section.
default:
{
// default switches injected before all explicit command-line switches

View file

@ -1,7 +1,19 @@
// See comments in driver/config.d in ldc source tree for grammar description of
// this config file.
// The default group is required
// For cross-compilation, you can add sections for specific target triples by
// naming the sections as (quoted) regex patterns. See LDC's `-v` output
// (`config` line) to figure out your normalized triple, depending on the used
// `-mtriple`, `-m32` etc. E.g.:
//
// "^arm.*-linux-gnueabihf$": { … };
// "86(_64)?-.*-linux": { … };
// "i[3-6]86-.*-windows-msvc": { … };
//
// Later sections take precedence and override settings from previous matching
// sections while inheriting unspecified settings from previous sections.
// A `default` section always matches (treated as ".*") and is therefore usually
// the first section.
default:
{
// default switches injected before all explicit command-line switches

View file

@ -2,7 +2,7 @@
// NOSWITCHES: Could not look up switches in {{.*}}noswitches.conf
// RUN: not %ldc -conf=%S/inputs/section_aaa.conf %s 2>&1 | FileCheck %s --check-prefix=NO_SEC
// NO_SEC: Could not look up section '{{.*}}' nor the 'default' section in {{.*}}section_aaa.conf
// NO_SEC: No matching section for triple '{{.*}}' in {{.*}}section_aaa.conf
void foo()

View file

@ -1,9 +1,9 @@
x86-apple-windows-msvc:
{
switches = [ "-version" ];
};
default:
{
switches = [ "" ];
};
x86-apple-windows-msvc:
{
switches = [ "-version" ];
};