13 const map<string, string> VuoCompilerCompatibility::knownPlatforms = {
17 const map<string, string> VuoCompilerCompatibility::knownArchitectures = {
18 {
"x86_64",
"an Intel (X86-64) CPU"},
19 {
"arm64",
"an Apple Silicon (M1/ARM64) CPU"}
34 json_object_get(json);
42 this->json = other.json;
45 json_object_get(json);
56 this->json = other.json;
59 json_object_get(json);
70 json_object_put(json);
80 if (! intersect.json || ! other.json)
81 return ! intersect.json && ! other.json;
83 return json_object_equal(intersect.json, other.json);
99 vector<string> platforms;
101 json_object_object_foreach(json, platform, val)
103 platforms.push_back(platform);
107 json_object_object_foreach(other.json, platform, val)
109 platforms.push_back(platform);
113 for (
string platform : platforms)
117 bool thisPlatformCompatible;
118 json_object *thisPlatformVal = findPlatform(json, platform, thisPlatformCompatible);
120 bool otherPlatformCompatible;
121 json_object *otherPlatformVal = findPlatform(other.json, platform, otherPlatformCompatible);
123 if (! (thisPlatformCompatible && otherPlatformCompatible))
125 json_object_object_add(intersect, platform.c_str(), json_object_new_boolean(
false));
129 if (! otherPlatformVal)
131 json_object_object_add(intersect, platform.c_str(), thisPlatformVal);
135 if (! thisPlatformVal)
137 json_object_object_add(intersect, platform.c_str(), otherPlatformVal);
143 vector<string> thisArchVec = findArchitectures(thisPlatformVal);
144 vector<string> otherArchVec = findArchitectures(otherPlatformVal);
146 vector<string> intersectArchVec;
147 if (thisArchVec.empty())
148 intersectArchVec = otherArchVec;
149 else if (otherArchVec.empty())
150 intersectArchVec = thisArchVec;
153 set_intersection(thisArchVec.begin(), thisArchVec.end(),
154 otherArchVec.begin(), otherArchVec.end(),
155 std::back_inserter(intersectArchVec));
157 if (intersectArchVec.empty())
159 json_object_object_add(intersect, platform.c_str(), json_object_new_boolean(
false));
165 if (! intersectArchVec.empty())
167 intersectArch = json_object_new_array_ext(intersectArchVec.size());
168 for (
size_t i = 0; i < intersectArchVec.size(); ++i)
170 json_object *a = json_object_new_string(intersectArchVec[i].c_str());
171 json_object_array_put_idx(intersectArch, i, a);
177 string thisMin = findVersion(thisPlatformVal,
"min");
178 string thisMax = findVersion(thisPlatformVal,
"max");
179 string otherMin = findVersion(otherPlatformVal,
"min");
180 string otherMax = findVersion(otherPlatformVal,
"max");
182 auto compareVersions = [](
const string &a,
const string &b)
186 for (
size_t i = 0; i < max(as.size(), bs.size()); ++i)
188 int ai = (i < as.size() ? atoi(as[i].c_str()) : 0);
189 int bi = (i < bs.size() ? atoi(bs[i].c_str()) : 0);
199 if (! thisMin.empty() || ! otherMin.empty())
202 greaterMin = otherMin;
203 else if (otherMin.empty())
204 greaterMin = thisMin;
207 vector<string> mins = {thisMin, otherMin};
208 sort(mins.begin(), mins.end(), compareVersions);
209 greaterMin = mins[1];
214 if (! thisMax.empty() || ! otherMax.empty())
217 lesserMax = otherMax;
218 else if (otherMax.empty())
222 vector<string> maxes = {thisMax, otherMax};
223 sort(maxes.begin(), maxes.end(), compareVersions);
224 lesserMax = maxes[0];
228 if (! greaterMin.empty() && ! lesserMax.empty())
230 vector<string> minMax = {greaterMin, lesserMax};
231 vector<string> sortedMinMax = minMax;
232 sort(sortedMinMax.begin(), sortedMinMax.end(), compareVersions);
233 if (minMax != sortedMinMax)
235 json_object_object_add(intersect, platform.c_str(), json_object_new_boolean(
false));
241 if (! greaterMin.empty())
242 intersectMinVersion = json_object_new_string(greaterMin.c_str());
245 if (! lesserMax.empty())
246 intersectMaxVersion = json_object_new_string(lesserMax.c_str());
250 if (intersectArch || intersectMinVersion || intersectMaxVersion)
252 json_object *intersectPlatform = json_object_new_object();
254 json_object_object_add(intersectPlatform,
"arch", intersectArch);
255 if (intersectMinVersion)
256 json_object_object_add(intersectPlatform,
"min", intersectMinVersion);
257 if (intersectMaxVersion)
258 json_object_object_add(intersectPlatform,
"max", intersectMaxVersion);
259 json_object_object_add(intersect, platform.c_str(), intersectPlatform);
272 return "any system that Vuo supports";
274 auto labelForKey = [](
const string &key,
const map<string, string> &keysAndLabels)
276 auto iter = keysAndLabels.find(key);
277 if (iter != keysAndLabels.end())
283 auto macOSDisplayName = [](
const string &version) {
284 if (version < "10.16" || version >=
"11")
289 if (parts.size() < 2)
292 return to_string(stoi(parts[1]) - 5);
295 vector<string> platformStrings;
296 json_object_object_foreach(json, platformKey, platformVal)
300 string p = labelForKey(platformKey, knownPlatforms);
304 string min = findVersion(platformVal,
"min");
305 string max = findVersion(platformVal,
"max");
308 if (! min.empty() || ! max.empty())
311 min = macOSDisplayName(min);
313 max = macOSDisplayName(max);
317 else if (min.empty())
318 versions = max +
" and below";
319 else if (max.empty())
320 versions = min +
" and above";
322 versions = min +
" through " + max;
327 vector<string> archKeys = findArchitectures(platformVal);
328 vector<string> archList;
329 std::transform(archKeys.begin(), archKeys.end(),
330 std::back_inserter(archList),
331 [&](
string a) { return labelForKey(a, knownArchitectures); });
334 if (! versions.empty())
336 if (! architectures.empty())
337 p +=
" on " + architectures;
338 platformStrings.push_back(p);
349 return json_object_to_json_string_ext(json, JSON_C_TO_STRING_PLAIN);
357 bool isPlatformCompatible;
358 findPlatform(json, platform.c_str(), isPlatformCompatible);
359 return isPlatformCompatible;
367 bool isPlatformCompatible;
368 json_object *platformVal = findPlatform(json, platform.c_str(), isPlatformCompatible);
372 if (json_object_object_get_ex(platformVal,
"min", &min))
373 return json_object_get_string(min);
387 string arch = parts.at(0);
395 version = parts.at(2).substr(6);
396 version = version.substr(0, version.rfind(
"."));
401 json_object *platformVal = json_object_new_object();
402 json_object_object_add(json, platform.c_str(), platformVal);
404 json_object *archVal = json_object_new_string(arch.c_str());
405 json_object *archArray = json_object_new_array_ext(1);
406 json_object_array_put_idx(archArray, 0, archVal);
407 json_object_object_add(platformVal,
"arch", archArray);
409 json_object *minVal = json_object_new_string(version.c_str());
410 json_object *maxVal = json_object_new_string(version.c_str());
411 json_object_object_add(platformVal,
"min", minVal);
412 json_object_object_add(platformVal,
"max", maxVal);
430 if (architectures.empty())
433 set<string> knownArchitectureKeys;
434 std::transform(knownArchitectures.begin(), knownArchitectures.end(),
435 std::inserter(knownArchitectureKeys, knownArchitectureKeys.end()),
436 [](
const pair<string, string> &p) { return p.first; });
437 if (knownArchitectureKeys == architectures)
440 json_object *archArray = json_object_new_array_ext(architectures.size());
442 for (
string arch : architectures)
444 json_object *archVal = json_object_new_string(arch.c_str());
445 json_object_array_put_idx(archArray, i++, archVal);
450 for (
auto platform : knownPlatforms)
452 json_object *platformVal = json_object_new_object();
453 json_object_object_add(json, platform.first.c_str(), platformVal);
455 json_object_object_add(platformVal,
"arch", archArray);
456 json_object_get(archArray);
459 json_object_put(archArray);
464 json_object * VuoCompilerCompatibility::findPlatform(
json_object *json,
string platformKey,
bool &isPlatformCompatible)
466 isPlatformCompatible =
true;
469 if (json_object_object_get_ex(json, platformKey.c_str(), &platformVal))
471 if (json_object_is_type(platformVal, json_type_boolean))
472 isPlatformCompatible =
false;
480 string VuoCompilerCompatibility::findVersion(
json_object *platformVal,
const string &minOrMax)
483 if (json_object_object_get_ex(platformVal, minOrMax.c_str(), &versionVal))
484 return json_object_get_string(versionVal);
489 vector<string> VuoCompilerCompatibility::findArchitectures(
json_object *platformVal)
491 vector<string> architectures;
494 if (json_object_object_get_ex(platformVal,
"arch", &arch))
496 size_t len = json_object_array_length(arch);
497 for (
size_t i = 0; i < len; ++i)
499 json_object *a = json_object_array_get_idx(arch, i);
500 architectures.push_back(json_object_get_string(a));
504 return architectures;