Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimized suffix checking. #47

Merged
merged 1 commit into from
Mar 16, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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;
}