first commit
This commit is contained in:
commit
c41c808834
12
.clang-format
Normal file
12
.clang-format
Normal file
@ -0,0 +1,12 @@
|
||||
# .clang-format
|
||||
|
||||
# 风格格式化
|
||||
BasedOnStyle: Google
|
||||
# 4 空格缩进
|
||||
IndentWidth: 4
|
||||
# 连续对齐变量的声明
|
||||
AlignConsecutiveDeclarations: true
|
||||
# 指针左侧对齐
|
||||
PointerAlignment: Left
|
||||
# 访问说明符(public、private等)的偏移
|
||||
AccessModifierOffset: -4
|
7
.clangd
Normal file
7
.clangd
Normal file
@ -0,0 +1,7 @@
|
||||
Hover:
|
||||
ShowAKA: Yes
|
||||
Diagnostics:
|
||||
UnusedIncludes: None
|
||||
Suppress: [anon_type_definition]
|
||||
ClangTidy:
|
||||
Remove: misc-unused-alias-decls
|
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
build
|
||||
cmake-build*
|
||||
.idea
|
||||
.vs
|
||||
.cache
|
34
.vscode/settings.json
vendored
Normal file
34
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
{
|
||||
"files.autoSave": "onFocusChange",
|
||||
"editor.fontSize": 17,
|
||||
"editor.fontFamily": "'Operator Mono Lig Light', 'Operator Mono Lig Light', 'Operator Mono Lig Light'",
|
||||
"editor.fontLigatures": true,
|
||||
"cmake.configureOnOpen": true,
|
||||
"cmake.generator": "Ninja",
|
||||
"cmake.debugConfig": {
|
||||
"console": "integratedTerminal",
|
||||
"args": [
|
||||
"G:\\ACode\\RTM_x64_vs2015\\RTM_x64_vs2015_Use.sln",
|
||||
"Debug|x64",
|
||||
"D:/he.json",
|
||||
"expect:..\\include"
|
||||
],
|
||||
},
|
||||
"cmake.options.statusBarVisibility": "visible",
|
||||
"editor.inlayHints.enabled": "off",
|
||||
"C_Cpp.intelliSenseEngine": "disabled",
|
||||
"clangd.arguments": [
|
||||
"--header-insertion=never",
|
||||
"--all-scopes-completion",
|
||||
"--completion-style=detailed",
|
||||
"-j=4",
|
||||
"--pch-storage=memory",
|
||||
"--compile-commands-dir=build",
|
||||
"--background-index",
|
||||
"--ranking-model=heuristics",
|
||||
"--query-driver=/usr/bin/g++"
|
||||
],
|
||||
"files.associations": {
|
||||
"filesystem": "cpp"
|
||||
}
|
||||
}
|
2
3rd/.gitignore
vendored
Normal file
2
3rd/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
jsoncpp-lib
|
||||
jsoncpp-1.9.5
|
1
3rd/build_command.txt
Normal file
1
3rd/build_command.txt
Normal file
@ -0,0 +1 @@
|
||||
cmake .. -A x64 -DCMAKE_INSTALL_PREFIX=G:\0516\vs_generate\3rd\jsoncpp-lib -DJSONCPP_WITH_CMAKE_PACKAGE=ON
|
BIN
3rd/jsoncpp-1.9.5.zip
Normal file
BIN
3rd/jsoncpp-1.9.5.zip
Normal file
Binary file not shown.
27
CMakeLists.txt
Normal file
27
CMakeLists.txt
Normal file
@ -0,0 +1,27 @@
|
||||
cmake_minimum_required (VERSION 3.8)
|
||||
cmake_policy(SET CMP0074 NEW)
|
||||
|
||||
project (vs_generate)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
set(PROJECT_SOURCE
|
||||
main.cpp vs_generate.cpp
|
||||
vs_generate.h tinyxml2.h tinyxml2.cpp
|
||||
vs_json.cpp vs_json.h
|
||||
)
|
||||
|
||||
set(JSONCPP_DIR ${CMAKE_CURRENT_SOURCE_DIR}/3rd/jsoncpp-lib)
|
||||
if (MSVC)
|
||||
string(APPEND CMAKE_CXX_FLAGS " /source-charset:utf-8 /EHsc")
|
||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
||||
endif()
|
||||
|
||||
include_directories(${JSONCPP_DIR}/include)
|
||||
link_directories(${JSONCPP_DIR}/lib)
|
||||
add_executable(vs_generate ${PROJECT_SOURCE})
|
||||
|
||||
if (${CMAKE_BUILD_TYPE} STREQUAL "Debug")
|
||||
target_link_libraries(vs_generate PRIVATE jsoncpp_staticD)
|
||||
else()
|
||||
target_link_libraries(vs_generate PRIVATE jsoncpp_static)
|
||||
endif()
|
3
README.md
Normal file
3
README.md
Normal file
@ -0,0 +1,3 @@
|
||||
# 说明
|
||||
|
||||
根据 vcxproj 或者 sln 工程文件导出 clangd 使用的 compile_commands.json 文件。
|
37
main.cpp
Normal file
37
main.cpp
Normal file
@ -0,0 +1,37 @@
|
||||
#include "vs_json.h"
|
||||
#define VS_GENERATE_VERSION "v1.0"
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
//
|
||||
if (argc != 5) {
|
||||
std::string help(VS_GENERATE_VERSION);
|
||||
help.append("\n");
|
||||
help.append(
|
||||
"vs_generate [xx.sln或xxx.vcxproj] [Debug|x64] [xxxx.json] "
|
||||
"[expect:xxx;ccc;]");
|
||||
help.append("\n expect选项没有则:后空着即可。");
|
||||
std::cout << help << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string sln_path(argv[1]);
|
||||
VsParseSln sln;
|
||||
if (!sln.parse(sln_path)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
VsParsePro pro{};
|
||||
auto projs = sln.get_project();
|
||||
for (auto& item : projs) {
|
||||
if (!pro.parse(&item, std::string(argv[2]))) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
JsonCommand command{};
|
||||
command.set_expect(std::string(argv[4]));
|
||||
command.set_out(std::string(argv[3]));
|
||||
command.generate(projs);
|
||||
|
||||
return 0;
|
||||
}
|
2986
tinyxml2.cpp
Normal file
2986
tinyxml2.cpp
Normal file
File diff suppressed because it is too large
Load Diff
2380
tinyxml2.h
Normal file
2380
tinyxml2.h
Normal file
File diff suppressed because it is too large
Load Diff
200
vs_generate.cpp
Normal file
200
vs_generate.cpp
Normal file
@ -0,0 +1,200 @@
|
||||
|
||||
#include "vs_generate.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <fstream>
|
||||
#include <regex>
|
||||
#include <string>
|
||||
|
||||
VsParseSln::VsParseSln() = default;
|
||||
|
||||
// 解析关联
|
||||
void VsParseSln::parse_relate() {
|
||||
for (auto& proj : projs_) {
|
||||
for (auto& relate : proj.guid_relate_) {
|
||||
std::string opth = hashmap_[relate];
|
||||
proj.relate_.push_back(opth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool VsParseSln::parse(const std::string& path) {
|
||||
std::ifstream sln_file(path, std::ios::in);
|
||||
if (!sln_file.is_open()) {
|
||||
std::cout << "没有找到 sln 文件或者打开文件失败,路径:" << path
|
||||
<< "\n";
|
||||
return false;
|
||||
}
|
||||
fs::path full_path(path);
|
||||
fs::path parent_path = full_path.parent_path();
|
||||
|
||||
projs_.clear();
|
||||
std::string tmp{};
|
||||
std::regex re(R"(\"(.*?)\")");
|
||||
std::regex re2(R"((\{.*?\}))");
|
||||
std::smatch match{};
|
||||
ProjectInfo proj{};
|
||||
bool related = false;
|
||||
bool add = false;
|
||||
while (std::getline(sln_file, tmp)) {
|
||||
if (tmp.find("Project") != std::string::npos &&
|
||||
tmp.find(".vcxproj") != std::string::npos) {
|
||||
std::vector<std::string> vec{};
|
||||
while (std::regex_search(tmp, match, re)) {
|
||||
vec.push_back(match[1]);
|
||||
tmp = match.suffix().str();
|
||||
}
|
||||
// 这里应该有4个结果
|
||||
assert(vec.size() == 4);
|
||||
proj.guid_ = vec[3];
|
||||
proj.path_ = parent_path.string() + "\\" + vec[2];
|
||||
add = true;
|
||||
}
|
||||
if (tmp.find("ProjectDependencies") != std::string::npos) {
|
||||
related = true;
|
||||
continue;
|
||||
}
|
||||
if (tmp.find("EndProjectSection") != std::string::npos) {
|
||||
related = false;
|
||||
continue;
|
||||
}
|
||||
if (related) {
|
||||
// 这里要简单处理一下
|
||||
if (std::regex_search(tmp, match, re2)) {
|
||||
std::string restr = match[1];
|
||||
proj.guid_relate_.push_back(restr);
|
||||
}
|
||||
}
|
||||
if (tmp.find("EndProject") != std::string::npos && add) {
|
||||
projs_.push_back(proj);
|
||||
hashmap_[proj.guid_] = proj.path_;
|
||||
proj.guid_relate_.clear();
|
||||
add = false;
|
||||
}
|
||||
}
|
||||
|
||||
parse_relate();
|
||||
sln_file.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<ProjectInfo> VsParseSln::get_project() const { return projs_; }
|
||||
|
||||
void VsParsePro::handle_include(tinyxml2::XMLElement* node,
|
||||
const std::string& key) const {
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
const char* data = node->Attribute("Condition");
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
if (std::string(data).find(key) == std::string::npos) {
|
||||
return;
|
||||
}
|
||||
tinyxml2::XMLElement* purpose = node->FirstChildElement();
|
||||
while (purpose) {
|
||||
const char* name = purpose->Name();
|
||||
if (std::strcmp(name, "IncludePath") != 0) {
|
||||
purpose = purpose->NextSiblingElement();
|
||||
continue;
|
||||
}
|
||||
const char* include_path = purpose->GetText();
|
||||
current_proj_->addtion_.append(";");
|
||||
current_proj_->addtion_.append(include_path);
|
||||
break;
|
||||
}
|
||||
}
|
||||
void VsParsePro::additon_include_and_predefine(tinyxml2::XMLElement* node,
|
||||
const std::string& key) const {
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
const char* data = node->Attribute("Condition");
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
if (std::string(data).find(key) == std::string::npos) {
|
||||
return;
|
||||
}
|
||||
tinyxml2::XMLElement* cl = get_child_element(node, "ClCompile");
|
||||
const tinyxml2::XMLElement* purpose =
|
||||
get_child_element(cl, "AdditionalIncludeDirectories");
|
||||
if (purpose) {
|
||||
const char* addtion_dir = purpose->GetText();
|
||||
current_proj_->addtion_.append(";");
|
||||
current_proj_->addtion_.append(addtion_dir);
|
||||
}
|
||||
|
||||
purpose = get_child_element(cl, "PreprocessorDefinitions");
|
||||
if (purpose) {
|
||||
const char* predefinition = purpose->GetText();
|
||||
current_proj_->predefinition_.append(";");
|
||||
current_proj_->predefinition_.append(predefinition);
|
||||
}
|
||||
}
|
||||
|
||||
tinyxml2::XMLElement* VsParsePro::get_child_element(tinyxml2::XMLElement* node,
|
||||
const std::string& key) {
|
||||
tinyxml2::XMLElement* result{};
|
||||
if (!node) {
|
||||
return result;
|
||||
}
|
||||
tinyxml2::XMLElement* n = node->FirstChildElement();
|
||||
while (n) {
|
||||
if (std::strcmp(n->Name(), key.c_str()) == 0) {
|
||||
result = n;
|
||||
break;
|
||||
}
|
||||
n = n->NextSiblingElement();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool VsParsePro::parse(ProjectInfo* proj, const std::string& key) {
|
||||
current_proj_ = proj;
|
||||
supplement(current_proj_);
|
||||
|
||||
int ret = m_doc_.LoadFile(current_proj_->path_.c_str());
|
||||
if (ret != 0) {
|
||||
std::cout << "解析失败:" << current_proj_->path_ << "\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
tinyxml2::XMLElement* element = m_doc_.FirstChildElement();
|
||||
if (std::strcmp(element->Name(), "Project") != 0) {
|
||||
std::cout << "不是合法的vcxproj文件。" << current_proj_->path_ << "\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
addition_dir_.clear();
|
||||
tinyxml2::XMLElement* node = element->FirstChildElement();
|
||||
while (node) {
|
||||
if (std::strcmp(node->Name(), "PropertyGroup") == 0) {
|
||||
handle_include(node, key);
|
||||
}
|
||||
if (std::strcmp(node->Name(), "ItemDefinitionGroup") == 0) {
|
||||
additon_include_and_predefine(node, key);
|
||||
}
|
||||
node = node->NextSiblingElement();
|
||||
}
|
||||
tidy(current_proj_);
|
||||
return true;
|
||||
}
|
||||
|
||||
// 对初步解析出的工程进行整理
|
||||
void VsParsePro::tidy(ProjectInfo* proj) {}
|
||||
|
||||
// 补充其他信息
|
||||
void VsParsePro::supplement(ProjectInfo* proj) {
|
||||
if (proj->path_.empty() || !fs::exists(proj->path_)) {
|
||||
return;
|
||||
}
|
||||
fs::path path(proj->path_);
|
||||
if (proj->proj_root_.empty()) {
|
||||
proj->proj_root_ = path.parent_path().string();
|
||||
}
|
||||
if (proj->name_.empty()) {
|
||||
proj->name_ = path.filename().string();
|
||||
}
|
||||
}
|
83
vs_generate.h
Normal file
83
vs_generate.h
Normal file
@ -0,0 +1,83 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "tinyxml2.h"
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__MINGW__)
|
||||
#define CPP_STANDARD _MSVC_LANG
|
||||
#else
|
||||
#define CPP_STANDARD __cplusplus
|
||||
#endif
|
||||
|
||||
#if CPP_STANDARD >= 201703L // 检查C++17或更高版本支持
|
||||
#include <filesystem>
|
||||
namespace fs = std::filesystem;
|
||||
#elif CPP_STANDARD >= 201402L // 检查C++14或更高版本支持
|
||||
#include <filesystem>
|
||||
namespace fs = std::experimental::filesystem;
|
||||
#else
|
||||
#error "不支持的C++标准版本"
|
||||
#endif
|
||||
|
||||
struct ProjectInfo {
|
||||
std::string proj_root_{};
|
||||
std::string path_{};
|
||||
std::string name_{};
|
||||
std::string guid_{};
|
||||
// addtion_ ; 分隔
|
||||
std::string addtion_{};
|
||||
// predefinitaion ; 分隔
|
||||
std::string predefinition_{};
|
||||
// 关联的工程名称
|
||||
std::vector<std::string> relate_{};
|
||||
// 关联的GUID
|
||||
std::vector<std::string> guid_relate_{};
|
||||
};
|
||||
|
||||
class VsParseSln {
|
||||
public:
|
||||
VsParseSln();
|
||||
~VsParseSln() = default;
|
||||
|
||||
public:
|
||||
bool parse(const std::string& path);
|
||||
std::vector<ProjectInfo> get_project() const;
|
||||
|
||||
private:
|
||||
// 解析关联
|
||||
void parse_relate();
|
||||
|
||||
private:
|
||||
std::vector<ProjectInfo> projs_{};
|
||||
std::unordered_map<std::string, std::string> hashmap_{};
|
||||
};
|
||||
|
||||
class VsParsePro {
|
||||
private:
|
||||
tinyxml2::XMLDocument m_doc_{};
|
||||
std::string addition_dir_{};
|
||||
ProjectInfo* current_proj_{};
|
||||
|
||||
public:
|
||||
VsParsePro() = default;
|
||||
~VsParsePro() = default;
|
||||
|
||||
private:
|
||||
void handle_include(tinyxml2::XMLElement* node, const std::string& key) const;
|
||||
void additon_include_and_predefine(tinyxml2::XMLElement* node,
|
||||
const std::string& key) const;
|
||||
static tinyxml2::XMLElement* get_child_element(tinyxml2::XMLElement* node,
|
||||
const std::string& key);
|
||||
// 对初步解析出的工程进行整理
|
||||
void tidy(ProjectInfo* proj);
|
||||
// 补充其他信息
|
||||
static void supplement(ProjectInfo* proj);
|
||||
|
||||
public:
|
||||
// 对给定的工程初步解析
|
||||
bool parse(ProjectInfo* proj, const std::string& key);
|
||||
};
|
167
vs_json.cpp
Normal file
167
vs_json.cpp
Normal file
@ -0,0 +1,167 @@
|
||||
#include "vs_json.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <list>
|
||||
#include <set>
|
||||
|
||||
JsonCommand::JsonCommand() = default;
|
||||
JsonCommand::~JsonCommand() = default;
|
||||
|
||||
void JsonCommand::set_expect(const std::string& exp) { expect_ = exp; }
|
||||
void JsonCommand::set_out(const std::string& out) { out_ = out; }
|
||||
|
||||
bool JsonCommand::generate(const std::vector<ProjectInfo>& projs) {
|
||||
Json::Value json_root{};
|
||||
for (const auto& item : projs) {
|
||||
const auto& cpps = get_cpp_paths(item.proj_root_);
|
||||
std::string command = get_command(&item, projs);
|
||||
for (const auto& cpp : cpps) {
|
||||
Json::Value jsn{};
|
||||
jsn["directory"] = item.proj_root_;
|
||||
jsn["command"] = command + " -c " + cpp; // NOLINT
|
||||
jsn["file"] = cpp;
|
||||
json_root.append(jsn);
|
||||
}
|
||||
}
|
||||
std::ofstream jsf(out_, std::ios::out);
|
||||
if (!jsf.is_open()) {
|
||||
std::cout << "不能打开文件:" << std::endl;
|
||||
return false;
|
||||
}
|
||||
jsf << json_root.toStyledString();
|
||||
jsf.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string JsonCommand::get_command(const ProjectInfo* proj,
|
||||
const std::vector<ProjectInfo>& projs) {
|
||||
std::string result{};
|
||||
result.append(
|
||||
R"("C:\PROGRA~2\Microsoft Visual Studio 14.0\VC\bin\amd64\cl.exe")");
|
||||
|
||||
std::string co_include = proj->addtion_;
|
||||
std::string co_predefinitions = proj->predefinition_;
|
||||
|
||||
std::string speciaA("$(IncludePath)");
|
||||
std::string speciaB("%(PreprocessorDefinitions)");
|
||||
std::string speciaC("%(AdditionalIncludeDirectories)");
|
||||
std::string speciaD("$(WindowsSDK_IncludePath)");
|
||||
std::string speciaE("$(VC_IncludePath)");
|
||||
|
||||
replaceAll(co_include, speciaA, "");
|
||||
replaceAll(co_include, speciaC, "");
|
||||
replaceAll(co_include, speciaD, "");
|
||||
replaceAll(co_include, speciaE, "");
|
||||
replaceAll(co_predefinitions, speciaB, "");
|
||||
|
||||
auto include_vec = split(co_include, ";");
|
||||
auto prede_vec = split(co_predefinitions, ";");
|
||||
|
||||
for (const auto& str : prede_vec) {
|
||||
if (str.empty()) {
|
||||
continue;
|
||||
}
|
||||
result.append(" -D" + str);
|
||||
}
|
||||
|
||||
for (const auto& str : include_vec) {
|
||||
if (str.empty()) {
|
||||
continue;
|
||||
}
|
||||
if (expect_.find(str) != std::string::npos) {
|
||||
continue;
|
||||
}
|
||||
result.append(" -I" + fs::path(proj->proj_root_).append(str).string());
|
||||
}
|
||||
|
||||
std::list<std::string> proj_list{};
|
||||
std::vector<std::string> re_relate{};
|
||||
auto handle = [&](const std::vector<std::string>& lrelate) {
|
||||
for (const auto& str : lrelate) {
|
||||
proj_list.push_back(str);
|
||||
}
|
||||
};
|
||||
|
||||
for (const auto& str : proj->guid_relate_) {
|
||||
// 这里的relate 子项目有别的依赖的话都需要加上
|
||||
// 这里假定不会出现循环引用的情况 (理论也不应该出现)
|
||||
for (const auto& pj : projs) {
|
||||
if (pj.guid_ == str) {
|
||||
handle(pj.guid_relate_);
|
||||
re_relate.push_back(pj.path_);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//std::string dir = fs::path(str).parent_path().string();
|
||||
//result.append(" -I" + dir);
|
||||
}
|
||||
|
||||
while (!proj_list.empty()) {
|
||||
std::string& data = proj_list.front();
|
||||
for (const auto& pj : projs) {
|
||||
if (data == pj.guid_) {
|
||||
handle(pj.guid_relate_);
|
||||
re_relate.push_back(pj.path_);
|
||||
break;
|
||||
}
|
||||
}
|
||||
proj_list.pop_front();
|
||||
}
|
||||
|
||||
// 去重
|
||||
std::set<std::string> no_reply{};
|
||||
for (const auto& str : re_relate) {
|
||||
no_reply.insert(str);
|
||||
}
|
||||
for (const auto& str : no_reply) {
|
||||
std::string dir = fs::path(str).parent_path().string();
|
||||
result.append(" -I" + dir);
|
||||
}
|
||||
|
||||
// std::cout << result << std::endl;
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<std::string> JsonCommand::split(const std::string& source,
|
||||
const std::string& sep) {
|
||||
std::vector<std::string> tokens;
|
||||
std::size_t start = 0;
|
||||
std::size_t end = 0;
|
||||
|
||||
while ((end = source.find(sep, start)) != std::string::npos) {
|
||||
tokens.push_back(source.substr(start, end - start));
|
||||
start = end + sep.length();
|
||||
}
|
||||
|
||||
tokens.push_back(source.substr(start));
|
||||
return tokens;
|
||||
}
|
||||
|
||||
std::vector<std::string> JsonCommand::get_cpp_paths(
|
||||
const std::string& parent_path) {
|
||||
std::vector<std::string> vec{};
|
||||
try {
|
||||
for (const auto& entry : fs::directory_iterator(parent_path)) {
|
||||
if (!fs::is_regular_file(entry.path())) {
|
||||
continue;
|
||||
}
|
||||
const fs::path& file_path(entry.path());
|
||||
if (file_path.extension().string() == ".cpp") {
|
||||
vec.push_back(file_path.string());
|
||||
}
|
||||
}
|
||||
} catch (fs::filesystem_error& e) {
|
||||
std::cout << "Error: " << e.what() << std::endl;
|
||||
}
|
||||
return vec;
|
||||
}
|
||||
|
||||
void JsonCommand::replaceAll(std::string& str, const std::string& from,
|
||||
const std::string& to) {
|
||||
size_t start_pos = 0;
|
||||
while ((start_pos = str.find(from, start_pos)) != std::string::npos) {
|
||||
str.replace(start_pos, from.length(), to);
|
||||
start_pos += to.length();
|
||||
}
|
||||
}
|
26
vs_json.h
Normal file
26
vs_json.h
Normal file
@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include <json/json.h>
|
||||
|
||||
#include "vs_generate.h"
|
||||
|
||||
class JsonCommand {
|
||||
public:
|
||||
JsonCommand();
|
||||
~JsonCommand();
|
||||
|
||||
public:
|
||||
bool generate(const std::vector<ProjectInfo>& projs);
|
||||
void set_expect(const std::string& exp);
|
||||
void set_out(const std::string& out);
|
||||
|
||||
private:
|
||||
std::string expect_{"expect"};
|
||||
std::string out_{"compile_commands.json" };
|
||||
std::string get_command(const ProjectInfo* proj, const std::vector<ProjectInfo>& projs);
|
||||
static std::vector<std::string> get_cpp_paths(const std::string& parent_path);
|
||||
static std::vector<std::string> split(const std::string& source,
|
||||
const std::string& sep);
|
||||
static void replaceAll(std::string& str, const std::string& from,
|
||||
const std::string& to);
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user