aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2015-12-02 14:24:10 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2015-12-02 14:45:13 +0200
commitbecea217436a79b7ef37a023da6cb4c560225a71 (patch)
tree5017f0ad3bc4d78ad737f4dc2b8b2036bb5f5664
parent685fe65f6b26b9e57c3d10cfe68c66d8baff8a68 (diff)
Redo extension derivation for file{}, doc{}, and cli{}
We now first check the 'extension' variable, then use the default.
-rw-r--r--build/cli/target.cxx6
-rw-r--r--build/cxx/target.cxx12
-rw-r--r--build/parser.cxx7
-rw-r--r--build/target5
-rw-r--r--build/target.cxx9
-rw-r--r--build/target.txx22
6 files changed, 39 insertions, 22 deletions
diff --git a/build/cli/target.cxx b/build/cli/target.cxx
index a480633..6eef99b 100644
--- a/build/cli/target.cxx
+++ b/build/cli/target.cxx
@@ -15,13 +15,15 @@ namespace build
{
// cli
//
- constexpr const char cli_ext[] = "cli";
+ constexpr const char cli_ext_var[] = "extension";
+ constexpr const char cli_ext_def[] = "cli";
+
const target_type cli::static_type
{
"cli",
&file::static_type,
&target_factory<cli>,
- &target_extension_fix<cli_ext>,
+ &target_extension_var<cli_ext_var, cli_ext_def>,
&search_file,
false
};
diff --git a/build/cxx/target.cxx b/build/cxx/target.cxx
index c8680b7..b84167b 100644
--- a/build/cxx/target.cxx
+++ b/build/cxx/target.cxx
@@ -16,7 +16,7 @@ namespace build
"hxx",
&file::static_type,
&target_factory<hxx>,
- &target_extension_var<hxx_ext_var>,
+ &target_extension_var<hxx_ext_var, nullptr>,
&search_file,
false
};
@@ -27,7 +27,7 @@ namespace build
"ixx",
&file::static_type,
&target_factory<ixx>,
- &target_extension_var<ixx_ext_var>,
+ &target_extension_var<ixx_ext_var, nullptr>,
&search_file,
false
};
@@ -38,7 +38,7 @@ namespace build
"txx",
&file::static_type,
&target_factory<txx>,
- &target_extension_var<txx_ext_var>,
+ &target_extension_var<txx_ext_var, nullptr>,
&search_file,
false
};
@@ -49,7 +49,7 @@ namespace build
"cxx",
&file::static_type,
&target_factory<cxx>,
- &target_extension_var<cxx_ext_var>,
+ &target_extension_var<cxx_ext_var, nullptr>,
&search_file,
false
};
@@ -60,7 +60,7 @@ namespace build
"h",
&file::static_type,
&target_factory<h>,
- &target_extension_var<h_ext_var>,
+ &target_extension_var<h_ext_var, nullptr>,
&search_file,
false
};
@@ -71,7 +71,7 @@ namespace build
"c",
&file::static_type,
&target_factory<c>,
- &target_extension_var<c_ext_var>,
+ &target_extension_var<c_ext_var, nullptr>,
&search_file,
false
};
diff --git a/build/parser.cxx b/build/parser.cxx
index c896c71..ee22254 100644
--- a/build/parser.cxx
+++ b/build/parser.cxx
@@ -818,6 +818,8 @@ namespace build
return r;
}
+ constexpr const char derived_ext_var[] = "extension";
+
void parser::
define (token& t, token_type& tt)
{
@@ -852,6 +854,11 @@ namespace build
dt->base = bt;
dt->factory = &derived_factory;
+ // Override extension derivation function: we most likely don't want
+ // to use the same default as our base (think cli: file).
+ //
+ dt->extension = &target_extension_var<derived_ext_var, nullptr>;
+
target_type& rdt (*dt); // Save a non-const reference to the object.
auto pr (scope_->target_types.emplace (dn, target_type_ref (move (dt))));
diff --git a/build/target b/build/target
index 2aea7ae..69f8f4f 100644
--- a/build/target
+++ b/build/target
@@ -1051,9 +1051,10 @@ namespace build
const std::string&
target_extension_fix (const target_key&, scope&);
- // Get the extension from the variable.
+ // Get the extension from the variable or use the default if none set.
+ // Issue diagnostics and fail if the default is NULL.
//
- template <const char* var>
+ template <const char* var, const char* def>
const std::string&
target_extension_var (const target_key&, scope&);
diff --git a/build/target.cxx b/build/target.cxx
index 5c31311..41fe54a 100644
--- a/build/target.cxx
+++ b/build/target.cxx
@@ -433,13 +433,15 @@ namespace build
(e != nullptr ? e : &extension_pool.find ("")));
}
- constexpr const char extension_var[] = "extension";
+ constexpr const char file_ext_var[] = "extension";
+ constexpr const char file_ext_def[] = "";
+
const target_type file::static_type
{
"file",
&path_target::static_type,
&file_factory<file>,
- &target_extension_var<extension_var>,
+ &target_extension_var<file_ext_var, file_ext_def>,
&search_file,
false
};
@@ -493,13 +495,12 @@ namespace build
false
};
- constexpr const char doc_ext[] = "";
const target_type doc::static_type
{
"doc",
&file::static_type,
&file_factory<doc>,
- &target_extension_fix<doc_ext>,
+ &target_extension_var<file_ext_var, file_ext_def>, // Same as file.
&search_file,
false
};
diff --git a/build/target.txx b/build/target.txx
index e347f77..89a402e 100644
--- a/build/target.txx
+++ b/build/target.txx
@@ -10,24 +10,27 @@
namespace build
{
template <const char* ext>
- const std::string&
+ const string&
target_extension_fix (const target_key&, scope&)
{
return extension_pool.find (ext);
}
- template <const char* var>
- const std::string&
+ template <const char* var, const char* def>
+ const string&
target_extension_var (const target_key& tk, scope& s)
{
// Include target type/pattern-specific variables.
//
- auto l (s.lookup (tk, var));
+ if (auto l = s.lookup (tk, var))
+ return extension_pool.find (as<string> (*l));
+
+ if (def != nullptr)
+ return extension_pool.find (def);
- if (!l)
{
diag_record dr;
- dr << fail << "no default extension in variable '" << var << "'"
+ dr << error << "no default extension in variable '" << var << "'"
<< info << "required to derive file name for ";
// This is a bit hacky: we may be dealing with a target (see
@@ -39,11 +42,14 @@ namespace build
dr << "target " << tk;
else
{
- const std::string* proj (nullptr); // Used for local prerequisites.
+ const string* proj (nullptr); // Used for local prerequisites.
dr << "prerequisite " << prerequisite_key {&proj, tk, &s};
}
+
+ dr << info << "perhaps you forgot to add "
+ << tk.type->name << "{*}: " << var << " = ...";
}
- return extension_pool.find (as<std::string> (*l));
+ throw failed ();
}
}