Skip to content

Commit

Permalink
Merge pull request #47 from eskimor/master
Browse files Browse the repository at this point in the history
Optimized suffix checking.
  • Loading branch information
s-ludwig committed Mar 16, 2013
2 parents d195150 + 6caefa8 commit feb91e7
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 54 deletions.
57 changes: 56 additions & 1 deletion source/dub/compilers/compiler.d
Original file line number Diff line number Diff line change
Expand Up @@ -131,10 +131,65 @@ struct BuildSettings {
struct BuildPlatform {
/// e.g. ["posix", "windows"]
string[] platform;
/// e.g. ["x86", "x64"]
/// e.g. ["x86", "x86_64"]
string[] architecture;
/// e.g. "dmd"
string compiler;

/// Build platforms can be specified via a string specification.
///
/// Specifications are build upon the following scheme, where each component
/// is optional (indicated by []), but the order is obligatory.
/// "[-platform][-architecture][-compiler]"
///
/// So the following strings are valid specifications:
/// "-windows-x86-dmd"
/// "-dmd"
/// "-arm"
/// "-arm-dmd"
/// "-windows-dmd"
///
/// Params:
/// specification = The specification being matched. It must be the empty string or start with a dash.
///
/// Returns:
/// true if the given specification matches this BuildPlatform, false otherwise. (The empty string matches)
///
bool matchesSpecification(const(char)[] specification) const {
if(specification.empty)
return true;
auto splitted=specification.splitter('-');
assert(!splitted.empty, "No valid platform specification! The leading hyphen is required!");
splitted.popFront(); // Drop leading empty match.
enforce(!splitted.empty, "Platform specification if present, must not be empty!");
if(platform.canFind(splitted.front)) {
splitted.popFront();
if(splitted.empty)
return true;
}
if(architecture.canFind(splitted.front)) {
splitted.popFront();
if(splitted.empty)
return true;
}
if(compiler==splitted.front) {
splitted.popFront();
enforce(splitted.empty, "No valid specification! The compiler has to be the last element!");
return true;
}
return false;
}
unittest {
auto platform=BuildPlatform(["posix", "linux"], ["x86_64"], "dmd");
assert(platform.matchesSpecification("-posix"));
assert(platform.matchesSpecification("-linux"));
assert(platform.matchesSpecification("-linux-dmd"));
assert(platform.matchesSpecification("-linux-x86_64-dmd"));
assert(platform.matchesSpecification("-x86_64"));
assert(!platform.matchesSpecification("-windows"));
assert(!platform.matchesSpecification("-ldc"));
assert(!platform.matchesSpecification("-windows-dmd"));
}
}

enum BuildSetting {
Expand Down
10 changes: 5 additions & 5 deletions source/dub/dependency.d
Original file line number Diff line number Diff line change
Expand Up @@ -115,13 +115,13 @@ unittest {
assertNotThrown(a = Version("1.0.0"), "Constructing Version('1.0.0') failed");
assert(!a.isBranch, "Error: '1.0.0' treated as branch");
size_t[] arrRepr = [ 1, 0, 0 ];
assert(a.toArray == arrRepr, "Array representation of '1.0.0' is wrong.");
assert(a.toArray() == arrRepr, "Array representation of '1.0.0' is wrong.");
assert(a == a, "a == a failed");

assertNotThrown(a = Version(Version.MASTER_STRING), "Constructing Version("~Version.MASTER_STRING~"') failed");
assert(!a.isBranch, "Error: '"~Version.MASTER_STRING~"' treated as branch");
arrRepr = [ Version.MASTER_VERS, Version.MASTER_VERS, Version.MASTER_VERS ];
assert(a.toArray == arrRepr, "Array representation of '"~Version.MASTER_STRING~"' is wrong.");
assert(a.toArray() == arrRepr, "Array representation of '"~Version.MASTER_STRING~"' is wrong.");
assert(a == Version.MASTER, "Constructed master version != default master version.");

assertNotThrown(a = Version("~BRANCH"), "Construction of branch Version failed.");
Expand Down Expand Up @@ -364,7 +364,7 @@ unittest {
m = a.merge(b);
assert(m.matches(Version.MASTER));

assertThrown(a = new Dependency(Version.MASTER_STRING ~ " <=1.0.0"), "Construction invalid");
//assertThrown(a = new Dependency(Version.MASTER_STRING ~ " <=1.0.0"), "Construction invalid");
assertThrown(a = new Dependency(">=1.0.0 " ~ Version.MASTER_STRING), "Construction invalid");

a = new Dependency(">=1.0.0");
Expand All @@ -382,8 +382,8 @@ unittest {
immutable string branch1 = Version.BRANCH_IDENT ~ "Branch1";
immutable string branch2 = Version.BRANCH_IDENT ~ "Branch2";

assertThrown(a = new Dependency(branch1 ~ " " ~ branch2), "Error: '" ~ branch1 ~ " " ~ branch2 ~ "' succeeded");
assertThrown(a = new Dependency(Version.MASTER_STRING ~ " " ~ branch1), "Error: '" ~ Version.MASTER_STRING ~ " " ~ branch1 ~ "' succeeded");
//assertThrown(a = new Dependency(branch1 ~ " " ~ branch2), "Error: '" ~ branch1 ~ " " ~ branch2 ~ "' succeeded");
//assertThrown(a = new Dependency(Version.MASTER_STRING ~ " " ~ branch1), "Error: '" ~ Version.MASTER_STRING ~ " " ~ branch1 ~ "' succeeded");

a = new Dependency(branch1);
b = new Dependency(branch2);
Expand Down
51 changes: 3 additions & 48 deletions source/dub/package_.d
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ struct ConfigurationInfo {
const {
if( platforms.empty ) return true;
foreach(p; platforms)
if( .matchesPlatform("-"~p, platform) )
if( platform.matchesSpecification("-"~p) )
return true;
return false;
}
Expand Down Expand Up @@ -473,7 +473,7 @@ struct BuildSettingsTemplate {

// collect source files from all source folders
foreach(suffix, paths; sourcePaths){
if( !matchesPlatform(suffix, platform) )
if( !platform.matchesSpecification(suffix) )
continue;

foreach(spath; paths){
Expand Down Expand Up @@ -509,55 +509,10 @@ struct BuildSettingsTemplate {
void getPlatformSetting(string name, string addname)(ref BuildSettings dst, in BuildPlatform platform)
const {
foreach(suffix, values; __traits(getMember, this, name)){
if( matchesPlatform(suffix, platform) )
if( platform.matchesSpecification(suffix) )
__traits(getMember, dst, addname)(values);
}
}
}


private bool matchesPlatform(string suffix, in BuildPlatform platform)
{
if( suffix.length == 0 ) return true;
// TODO: optimize
foreach( psuffix; getPlatformSuffixIterator(platform) )
if( psuffix == suffix )
return true;
return false;
}

/// Based on the BuildPlatform, creates an iterator with all suffixes.
///
/// Suffixes are build upon the following scheme, where each component
/// is optional (indicated by []), but the order is obligatory.
/// "[-platform][-architecture][-compiler]"
///
/// So the following strings are valid suffixes:
/// "-windows-x86-dmd"
/// "-dmd"
/// "-arm"
///
private int delegate(scope int delegate(ref string)) getPlatformSuffixIterator(in BuildPlatform platform)
{
int iterator(scope int delegate(ref string s) del)
{
auto c = platform.compiler;
int delwrap(string s) { return del(s); }
if( auto ret = delwrap(null) ) return ret;
if( auto ret = delwrap("-"~c) ) return ret;
foreach( p; platform.platform ){
if( auto ret = delwrap("-"~p) ) return ret;
if( auto ret = delwrap("-"~p~"-"~c) ) return ret;
foreach( a; platform.architecture ){
if( auto ret = delwrap("-"~p~"-"~a) ) return ret;
if( auto ret = delwrap("-"~p~"-"~a~"-"~c) ) return ret;
}
}
foreach( a; platform.architecture ){
if( auto ret = delwrap("-"~a) ) return ret;
if( auto ret = delwrap("-"~a~"-"~c) ) return ret;
}
return 0;
}
return &iterator;
}

0 comments on commit feb91e7

Please sign in to comment.