Skip to content

Commit a6a3177

Browse files
committed
Clone merged fields to prevent links creation.
1 parent 14a5e83 commit a6a3177

File tree

5 files changed

+48
-22
lines changed

5 files changed

+48
-22
lines changed

src/common/project.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,7 @@ void Project::save_dependencies(yaml &node) const
532532
{
533533
if (dependencies.empty())
534534
return;
535+
535536
yaml root;
536537
for (auto &dd : dependencies)
537538
{

src/common/project_path.cpp

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -178,18 +178,36 @@ ProjectPath ProjectPath::operator[](PathElementType e) const
178178
return *this;
179179
}
180180

181-
bool ProjectPath::is_root_of(const ProjectPath &p) const
181+
bool ProjectPath::is_root_of(const ProjectPath &rhs) const
182182
{
183-
if (path_elements.size() >= p.path_elements.size())
183+
if (path_elements.size() >= rhs.path_elements.size())
184184
return false;
185185
for (size_t i = 0; i < path_elements.size(); i++)
186186
{
187-
if (path_elements[i] != p.path_elements[i])
187+
if (path_elements[i] != rhs.path_elements[i])
188188
return false;
189189
}
190190
return true;
191191
}
192192

193+
ProjectPath ProjectPath::back(const ProjectPath &root) const
194+
{
195+
ProjectPath p;
196+
if (!root.is_root_of(*this))
197+
return p;
198+
for (size_t i = 0; i < root.path_elements.size(); i++)
199+
{
200+
if (path_elements[i] != root.path_elements[i])
201+
{
202+
p.path_elements.assign(path_elements.begin() + i, path_elements.end());
203+
break;
204+
}
205+
}
206+
if (p.path_elements.empty())
207+
p.path_elements.assign(path_elements.end() - (path_elements.size() - root.path_elements.size()), path_elements.end());
208+
return p;
209+
}
210+
193211
void ProjectPath::push_back(const PathElement &pe)
194212
{
195213
path_elements.push_back(pe);

src/common/project_path.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ class ProjectPath
9999
{
100100
return path_elements.back();
101101
}
102+
ProjectPath back(const ProjectPath &root) const;
102103

103104
void push_back(const PathElement &pe);
104105

@@ -146,7 +147,7 @@ class ProjectPath
146147

147148
bool is_absolute(const String &username = String()) const;
148149
bool is_relative(const String &username = String()) const;
149-
bool is_root_of(const ProjectPath &p) const;
150+
bool is_root_of(const ProjectPath &rhs) const;
150151

151152
PathElement get_owner() const;
152153
auto get_name() const { return back(); }

src/common/yaml.cpp

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -27,22 +27,24 @@
2727

2828
#include "yaml.h"
2929

30-
void merge(yaml &to, const yaml &from, const YamlMergeFlags &flags)
30+
// no links allowed
31+
// to do this we call YAML::Clone()
32+
void merge(yaml &dst, const yaml &src, const YamlMergeFlags &flags)
3133
{
32-
if (!from.IsDefined())
34+
if (!src.IsDefined())
3335
return;
3436

35-
// if 'to' node is not a map, make it so
36-
if (!to.IsMap())
37-
to = yaml();
37+
// if 'dst' node is not a map, make it so
38+
if (!dst.IsMap())
39+
dst = yaml();
3840

39-
for (auto &f : from)
41+
for (auto &f : src)
4042
{
4143
auto sf = f.first.as<String>();
4244
auto ff = f.second.Type();
4345

4446
bool found = false;
45-
for (auto t : to)
47+
for (auto t : dst)
4648
{
4749
const auto st = t.first.as<String>();
4850
if (sf == st)
@@ -57,11 +59,11 @@ void merge(yaml &to, const yaml &from, const YamlMergeFlags &flags)
5759
yaml nn;
5860
nn.push_back(t.second);
5961
nn.push_back(f.second);
60-
to[st] = nn;
62+
dst[st] = nn;
6163
break;
6264
}
6365
case YamlMergeFlags::OverwriteScalars:
64-
to[st] = from[sf];
66+
dst[st] = YAML::Clone(src[sf]);
6567
break;
6668
case YamlMergeFlags::DontTouchScalars:
6769
break;
@@ -75,12 +77,12 @@ void merge(yaml &to, const yaml &from, const YamlMergeFlags &flags)
7577
{
7678
yaml nn = YAML::Clone(f);
7779
nn.push_back(t.second);
78-
to[st] = nn;
80+
dst[st] = nn;
7981
}
8082
else if (ff == YAML::NodeType::Sequence && ft == YAML::NodeType::Sequence)
8183
{
8284
for (auto &fv : f)
83-
t.second.push_back(fv);
85+
t.second.push_back(YAML::Clone(fv));
8486
}
8587
else if (ff == YAML::NodeType::Map && ft == YAML::NodeType::Map)
8688
merge(t.second, f.second);
@@ -91,16 +93,19 @@ void merge(yaml &to, const yaml &from, const YamlMergeFlags &flags)
9193
}
9294
if (!found)
9395
{
94-
to[sf] = f.second;
96+
dst[sf] = YAML::Clone(f.second);
9597
}
9698
}
9799
}
98100

99-
void prepare_yaml_config(yaml &root)
101+
void prepare_yaml_config(yaml root)
100102
{
101103
// can be all node checks from config, project, settings moved here?
102104

103-
//
105+
// no effect
106+
if (!root.IsMap())
107+
return;
108+
104109
auto prjs = root["projects"];
105110
if (prjs.IsDefined() && !prjs.IsMap())
106111
throw std::runtime_error("'projects' should be a map");
@@ -151,7 +156,7 @@ void prepare_yaml_config(yaml &root)
151156
CHECK_BSI("post_alias");
152157
#undef CHECK_BSI
153158

154-
root[kv.first] = kv.second;
159+
root[kv.first] = YAML::Clone(kv.second);
155160
}
156161
}
157162
}
@@ -165,8 +170,9 @@ void prepare_yaml_config(yaml &root)
165170
{
166171
YamlMergeFlags flags;
167172
flags.scalar_scalar = YamlMergeFlags::DontTouchScalars;
168-
merge(prj, root["source"], flags);
169-
merge(prj, root["version"], flags);
173+
merge(prj.second["source"], root["source"], flags);
174+
if (!prj.second["version"].IsDefined() && root["version"].IsDefined())
175+
prj.second["version"] = YAML::Clone(root["version"]);
170176
}
171177
}
172178
}

src/common/yaml.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ struct YamlMergeFlags
234234
int scalar_scalar = 0;
235235
};
236236

237-
void merge(yaml &to, const yaml &from, const YamlMergeFlags &flags = YamlMergeFlags());
237+
void merge(yaml &dst, const yaml &src, const YamlMergeFlags &flags = YamlMergeFlags());
238238

239239
yaml load_yaml_config(const path &p);
240240
yaml load_yaml_config(const String &s);

0 commit comments

Comments
 (0)