mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-11 21:37:17 +03:00
Config file: Treat section names as target triple regexps (#2718)
This commit is contained in:
parent
7816e7730a
commit
ddbd77c009
10 changed files with 109 additions and 72 deletions
|
@ -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 ..
|
||||
|
|
|
@ -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" ]);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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"));
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
14
ldc2.conf.in
14
ldc2.conf.in
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
x86-apple-windows-msvc:
|
||||
{
|
||||
switches = [ "-version" ];
|
||||
};
|
||||
|
||||
default:
|
||||
{
|
||||
switches = [ "" ];
|
||||
};
|
||||
|
||||
x86-apple-windows-msvc:
|
||||
{
|
||||
switches = [ "-version" ];
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue