aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaMont Jones <lamontjones@google.com>2023-06-02 21:34:19 +0000
committerCole Faust <colecfaust@gmail.com>2023-06-21 12:30:10 -0700
commite361127627b94b6eeaf8522941bb1220342a5554 (patch)
treec7e7b0b8f89d8b1035091d8fa1c77cc92fd7957b
parenta420c70e1a2fac2b5597b6a9a8f522e0448a38ce (diff)
downloadkati-e361127627b94b6eeaf8522941bb1220342a5554.tar.gz
Add KATI_foreach_sep function
syntax: $(KATI_foreach_sep var,separator,list,text) Rather than using a space to separate items in the expanded result, `separator` is used. comma := , v := $(KATI_foreach_sep w,$(comma) ,a b c,"$(w)") v will be set to: `"a", "b", "c"` Change-Id: I426d7b24846dc495b9134319dd452809837fe5f9
-rw-r--r--src/expr.cc2
-rw-r--r--src/func.cc23
-rw-r--r--src/strutil.cc6
-rw-r--r--src/strutil.h2
-rw-r--r--testcase/foreach.mk8
5 files changed, 34 insertions, 7 deletions
diff --git a/src/expr.cc b/src/expr.cc
index 41b60bb..e3a8629 100644
--- a/src/expr.cc
+++ b/src/expr.cc
@@ -215,7 +215,7 @@ class VarSubst : public Value {
WordWriter ww(s);
Pattern pat(pat_str);
for (std::string_view tok : WordScanner(value)) {
- ww.MaybeAddWhitespace();
+ ww.MaybeAddSeparator();
pat.AppendSubstRef(tok, subst, s);
}
}
diff --git a/src/func.cc b/src/func.cc
index 316e423..d5bca3a 100644
--- a/src/func.cc
+++ b/src/func.cc
@@ -108,7 +108,7 @@ void PatsubstFunc(const std::vector<Value*>& args,
WordWriter ww(s);
Pattern pat(pat_str);
for (std::string_view tok : WordScanner(str)) {
- ww.MaybeAddWhitespace();
+ ww.MaybeAddSeparator();
pat.AppendSubst(tok, repl, s);
}
}
@@ -721,12 +721,30 @@ void ForeachFunc(const std::vector<Value*>& args,
std::unique_ptr<SimpleVar> v(
new SimpleVar(std::string(tok), VarOrigin::AUTOMATIC, nullptr, Loc()));
ScopedGlobalVar sv(Intern(varname), v.get());
- ww.MaybeAddWhitespace();
+ ww.MaybeAddSeparator();
args[2]->Eval(ev, s);
}
ev->IncrementEvalDepth();
}
+void ForeachWithSepFunc(const std::vector<Value*>& args,
+ Evaluator* ev,
+ std::string* s) {
+ const std::string&& varname = args[0]->Eval(ev);
+ const std::string&& separator = args[1]->Eval(ev);
+ const std::string&& list = args[2]->Eval(ev);
+ ev->DecrementEvalDepth();
+ WordWriter ww(s);
+ for (std::string_view tok : WordScanner(list)) {
+ std::unique_ptr<SimpleVar> v(
+ new SimpleVar(std::string(tok), VarOrigin::AUTOMATIC, nullptr, Loc()));
+ ScopedGlobalVar sv(Intern(varname), v.get());
+ ww.MaybeAddSeparator(separator);
+ args[3]->Eval(ev, s);
+ }
+ ev->IncrementEvalDepth();
+}
+
void OriginFunc(const std::vector<Value*>& args,
Evaluator* ev,
std::string* s) {
@@ -1112,6 +1130,7 @@ static const std::unordered_map<std::string_view, FuncInfo> g_func_info_map = {
ENTRY("KATI_extra_file_deps", &ExtraFileDepsFunc, 0, 0, false, false),
ENTRY("KATI_shell_no_rerun", &ShellFuncNoRerun, 1, 1, false, false),
+ ENTRY("KATI_foreach_sep", &ForeachWithSepFunc, 4, 4, false, false),
};
} // namespace
diff --git a/src/strutil.cc b/src/strutil.cc
index 0a222ad..149c729 100644
--- a/src/strutil.cc
+++ b/src/strutil.cc
@@ -83,16 +83,16 @@ void WordScanner::Split(std::vector<std::string_view>* o) {
WordWriter::WordWriter(std::string* o) : out_(o), needs_space_(false) {}
-void WordWriter::MaybeAddWhitespace() {
+void WordWriter::MaybeAddSeparator(std::string_view sep) {
if (needs_space_) {
- out_->push_back(' ');
+ out_->append(sep);
} else {
needs_space_ = true;
}
}
void WordWriter::Write(std::string_view s) {
- MaybeAddWhitespace();
+ MaybeAddSeparator();
out_->append(s);
}
diff --git a/src/strutil.h b/src/strutil.h
index e199e14..bd71c1b 100644
--- a/src/strutil.h
+++ b/src/strutil.h
@@ -47,7 +47,7 @@ class WordScanner {
class WordWriter {
public:
explicit WordWriter(std::string* o);
- void MaybeAddWhitespace();
+ void MaybeAddSeparator(std::string_view sep = " ");
void Write(std::string_view s);
private:
diff --git a/testcase/foreach.mk b/testcase/foreach.mk
index 3dde97a..e1b8a00 100644
--- a/testcase/foreach.mk
+++ b/testcase/foreach.mk
@@ -1,7 +1,15 @@
base := base
dirs := a b c d
dir := FAIL
+comma := ,
files := $(foreach dir,$(dirs),$(foreach subdir,$(dirs),$(dir)/$(subdir)/$(base)))
+ifdef KATI
+files2 := $(KATI_foreach_sep dir,$(comma) ,$(dirs),"$(dir)")
+else
+# Since make doesn't have the function, manually set the result.
+files2 := "a", "b", "c", "d"
+endif
test:
echo $(files)
+ echo $(files2)