aboutsummaryrefslogtreecommitdiff
path: root/src/func.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/func.cc')
-rw-r--r--src/func.cc57
1 files changed, 56 insertions, 1 deletions
diff --git a/src/func.cc b/src/func.cc
index 75a7cb6..b3e544c 100644
--- a/src/func.cc
+++ b/src/func.cc
@@ -27,6 +27,7 @@
#include <algorithm>
#include <iterator>
#include <memory>
+#include <sstream>
#include <unordered_map>
#include "eval.h"
@@ -510,7 +511,7 @@ void EvalFunc(const std::vector<Value*>& args, Evaluator* ev, std::string*) {
}
}
-//#define TEST_FIND_EMULATOR
+// #define TEST_FIND_EMULATOR
// A hack for Android build. We need to evaluate things like $((3+4))
// when we emit ninja file, because the result of such expressions
@@ -656,6 +657,59 @@ void ShellFuncNoRerun(const std::vector<Value*>& args,
ShellStatusVar::SetValue(returnCode);
}
+void VarVisibilityFunc(const std::vector<Value*>& args,
+ Evaluator* ev,
+ std::string*) {
+ std::string arg = args[0]->Eval(ev);
+ std::vector<std::string> prefixes;
+
+ std::stringstream ss(args[1]->Eval(ev));
+ std::string prefix;
+ while (ss >> prefix) {
+ if (HasPrefix(prefix, "/")) {
+ ERROR_LOC(ev->loc(), "Visibility prefix should not start with /");
+ }
+ if (HasPrefix(prefix, "../")) {
+ ERROR_LOC(ev->loc(), "Visibility prefix should not start with ../");
+ }
+
+ std::string normalizedPrefix = prefix;
+ NormalizePath(&normalizedPrefix);
+ if (prefix != normalizedPrefix) {
+ ERROR_LOC(ev->loc(),
+ "Visibility prefix %s is not normalized. Normalized prefix: %s",
+ prefix.c_str(), normalizedPrefix.c_str());
+ }
+
+ // one visibility prefix cannot be the prefix of another visibility prefix
+ for (std::vector<std::string>::iterator it = prefixes.begin();
+ it != prefixes.end(); ++it) {
+ if (HasPathPrefix(*it, prefix)) {
+ ERROR_LOC(ev->loc(),
+ "Visibility prefix %s is the prefix of another visibility "
+ "prefix %s",
+ prefix.c_str(), it->c_str());
+ } else if (HasPathPrefix(prefix, *it)) {
+ ERROR_LOC(ev->loc(),
+ "Visibility prefix %s is the prefix of another visibility "
+ "prefix %s",
+ it->c_str(), prefix.c_str());
+ }
+ }
+
+ prefixes.push_back(prefix);
+ }
+
+ Symbol sym = Intern(arg);
+ Var* v = ev->PeekVar(sym);
+ // If variable is not defined, create an empty variable.
+ if (!v->IsDefined()) {
+ v = new SimpleVar(VarOrigin::FILE, ev->CurrentFrame(), ev->loc());
+ sym.SetGlobalVar(v, false, nullptr);
+ }
+ v->SetVisibilityPrefix(prefixes, sym.c_str());
+}
+
void CallFunc(const std::vector<Value*>& args, Evaluator* ev, std::string* s) {
static const Symbol tmpvar_names[] = {
Intern("0"), Intern("1"), Intern("2"), Intern("3"), Intern("4"),
@@ -1149,6 +1203,7 @@ static const std::unordered_map<std::string_view, FuncInfo> g_func_info_map = {
ENTRY("KATI_shell_no_rerun", &ShellFuncNoRerun, 1, 1, false, false),
ENTRY("KATI_foreach_sep", &ForeachWithSepFunc, 4, 4, false, false),
ENTRY("KATI_file_no_rerun", &FileFuncNoRerun, 2, 1, false, false),
+ ENTRY("KATI_visibility_prefix", &VarVisibilityFunc, 2, 1, false, false),
};
} // namespace