mirror of
https://github.com/github/codeql.git
synced 2025-12-18 01:33:15 +01:00
Swift: split Xcode autobuild
This commit is contained in:
62
swift/xcode-autobuilder/XcodeWorkspaceParser.cpp
Normal file
62
swift/xcode-autobuilder/XcodeWorkspaceParser.cpp
Normal file
@@ -0,0 +1,62 @@
|
||||
#include <libxml/tree.h>
|
||||
#include <libxml/parser.h>
|
||||
#include <iostream>
|
||||
#include "XcodeWorkspaceParser.h"
|
||||
|
||||
/*
|
||||
Extracts FileRef locations from an XML of the following form:
|
||||
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace version = "1.0">
|
||||
<FileRef location = "group:PathToProject.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
||||
*/
|
||||
std::vector<fs::path> readProjectsFromWorkspace(const std::string& workspace) {
|
||||
fs::path workspacePath(workspace);
|
||||
auto workspaceData = workspacePath / "contents.xcworkspacedata";
|
||||
if (!fs::exists(workspaceData)) {
|
||||
std::cerr << "[xcode autobuilder] Cannot read workspace: file does not exist '" << workspaceData
|
||||
<< "\n";
|
||||
return {};
|
||||
}
|
||||
|
||||
auto xmlDoc = xmlParseFile(workspaceData.c_str());
|
||||
if (!xmlDoc) {
|
||||
std::cerr << "[xcode autobuilder] Cannot parse workspace file '" << workspaceData << "\n";
|
||||
return {};
|
||||
}
|
||||
auto root = xmlDocGetRootElement(xmlDoc);
|
||||
auto first = xmlFirstElementChild(root);
|
||||
auto last = xmlLastElementChild(root);
|
||||
std::vector<xmlNodePtr> children;
|
||||
for (; first != last; first = xmlNextElementSibling(first)) {
|
||||
children.push_back(first);
|
||||
}
|
||||
children.push_back(first);
|
||||
std::vector<std::string> locations;
|
||||
for (auto child : children) {
|
||||
if (child) {
|
||||
auto prop = xmlGetProp(child, xmlCharStrdup("location"));
|
||||
if (prop) {
|
||||
locations.emplace_back((char*)prop);
|
||||
}
|
||||
}
|
||||
}
|
||||
xmlFreeDoc(xmlDoc);
|
||||
|
||||
std::vector<fs::path> projects;
|
||||
for (auto& location : locations) {
|
||||
auto colon = location.find(':');
|
||||
if (colon != std::string::npos) {
|
||||
auto project = location.substr(colon + 1);
|
||||
if (!project.empty()) {
|
||||
auto fullPath = workspacePath.parent_path() / project;
|
||||
projects.push_back(fullPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return projects;
|
||||
}
|
||||
Reference in New Issue
Block a user