#include "cmake.h" #include "sourcefile.h" #include #include "singletons.h" #include //TODO: remove using namespace std; //TODO: remove CMake::CMake(const boost::filesystem::path &path) { const auto find_cmake_project=[this](const boost::filesystem::path &cmake_path) { for(auto &line: juci::filesystem::read_lines(cmake_path)) { const std::regex project_regex("^ *project *\\(.*$"); std::smatch sm; if(std::regex_match(line, sm, project_regex)) { return true; } } return false; }; auto search_path=boost::filesystem::path(path); auto search_cmake_path=search_path; search_cmake_path+="/CMakeLists.txt"; if(boost::filesystem::exists(search_cmake_path)) paths.emplace(paths.begin(), search_cmake_path); if(find_cmake_project(search_cmake_path)) project_path=search_path; else { do { search_path=search_path.parent_path(); search_cmake_path=search_path; search_cmake_path+="/CMakeLists.txt"; if(boost::filesystem::exists(search_cmake_path)) paths.emplace(paths.begin(), search_cmake_path); if(find_cmake_project(search_cmake_path)) { project_path=search_path; break; } } while(search_path!=search_path.root_directory()); } if(project_path!="") { if(boost::filesystem::exists(project_path.string()+"/CMakeLists.txt") && !boost::filesystem::exists(project_path.string()+"/compile_commands.json")) create_compile_commands(project_path); } } bool CMake::create_compile_commands(const boost::filesystem::path &path) { Singleton::terminal()->print("Creating "+path.string()+"/compile_commands.json\n"); //TODO: Windows... if(Singleton::terminal()->execute(Singleton::Config::terminal()->cmake_command+" . -DCMAKE_EXPORT_COMPILE_COMMANDS=ON", path)==EXIT_SUCCESS) return true; return false; } void CMake::read_files() { for(auto &path: paths) files.emplace_back(juci::filesystem::read(path)); } void CMake::remove_tabs() { for(auto &file: files) { for(auto &chr: file) { if(chr=='\t') chr=' '; } } } void CMake::remove_comments() { for(auto &file: files) { size_t pos=0; size_t comment_start; bool inside_comment=false; while(posstart_line) { auto line=file.substr(start_line, end_line-start_line); const std::regex set_regex("^ *set *\\( *([A-Za-z_][A-Za-z_0-9]*) +(.*)\\) *$"); std::smatch sm; if(std::regex_match(line, sm, set_regex)) { std::string data=sm[2]; while(data.size()>0 && data.back()==' ') data.pop_back(); parse_variable_parameters(data); variables[sm[1]]=data; } } pos=end_line+1; } } } void CMake::parse_variable_parameters(std::string &data) { size_t pos=0; bool inside_quote=false; char last_char=0; while(pos CMake::get_function_parameters(std::string &data) { std::vector parameters; size_t pos=0; size_t parameter_pos=0; bool inside_quote=false; char last_char=0; while(pos > > CMake::get_functions_parameters(const std::string &name) { if(!parsed) parse(); std::vector > > functions; size_t file_c=0; for(auto &file: files) { size_t pos=0; while(posstart_line) { auto line=file.substr(start_line, end_line-start_line); const std::regex function_regex("^ *"+name+" *\\( *(.*)\\) *$"); std::smatch sm; if(std::regex_match(line, sm, function_regex)) { std::string data=sm[1]; while(data.size()>0 && data.back()==' ') data.pop_back(); auto parameters=get_function_parameters(data); functions.emplace(functions.begin(), paths[file_c], parameters); } } pos=end_line+1; } file_c++; } return functions; }