#include "project.h" #include "config.h" #include "terminal.h" #include "filesystem.h" #include std::unordered_map Project::run_arguments; std::unordered_map Project::debug_run_arguments; std::atomic Project::compiling(false); std::atomic Project::debugging(false); std::unique_ptr ProjectClang::get_cmake() { boost::filesystem::path path; if(!file_path.empty()) path=file_path.parent_path(); else path=Directories::get().current_path; if(path.empty()) return nullptr; auto cmake=std::unique_ptr(new CMake(path)); if(cmake->project_path.empty()) return nullptr; if(!CMake::create_default_build(cmake->project_path)) return nullptr; return cmake; } std::pair ProjectClang::get_run_arguments() { auto cmake=get_cmake(); if(!cmake) return {"", ""}; auto project_path=cmake->project_path.string(); auto run_arguments_it=run_arguments.find(project_path); std::string arguments; if(run_arguments_it!=run_arguments.end()) arguments=run_arguments_it->second; if(arguments.empty()) { auto executable=cmake->get_executable(file_path).string(); if(executable!="") { auto project_path=cmake->project_path; auto default_build_path=CMake::get_default_build_path(project_path); if(!default_build_path.empty()) { size_t pos=executable.find(project_path.string()); if(pos!=std::string::npos) executable.replace(pos, project_path.string().size(), default_build_path.string()); } arguments=filesystem::escape_argument(executable); } else arguments=filesystem::escape_argument(CMake::get_default_build_path(cmake->project_path)); } return {project_path, arguments}; } void ProjectClang::compile() { auto cmake=get_cmake(); if(!cmake) return; auto default_build_path=CMake::get_default_build_path(cmake->project_path); if(default_build_path.empty()) return; compiling=true; Terminal::get().print("Compiling project "+cmake->project_path.string()+"\n"); Terminal::get().async_process(Config::get().terminal.make_command, default_build_path, [this](int exit_status) { compiling=false; }); } void ProjectClang::compile_and_run() { auto cmake=get_cmake(); if(!cmake) return; auto project_path=cmake->project_path; auto default_build_path=CMake::get_default_build_path(project_path); if(default_build_path.empty()) return; auto run_arguments_it=run_arguments.find(project_path.string()); std::string arguments; if(run_arguments_it!=run_arguments.end()) arguments=run_arguments_it->second; if(arguments.empty()) { arguments=cmake->get_executable(file_path).string(); if(arguments.empty()) { Terminal::get().print("Could not find add_executable in the following paths:\n"); for(auto &path: cmake->paths) Terminal::get().print(" "+path.string()+"\n"); Terminal::get().print("Solution: either use Project Set Run Arguments, or open a source file within a directory where add_executable is set.\n", true); return; } size_t pos=arguments.find(project_path.string()); if(pos!=std::string::npos) arguments.replace(pos, project_path.string().size(), default_build_path.string()); arguments=filesystem::escape_argument(arguments); } compiling=true; Terminal::get().print("Compiling and running "+arguments+"\n"); Terminal::get().async_process(Config::get().terminal.make_command, default_build_path, [this, arguments, default_build_path](int exit_status){ compiling=false; if(exit_status==EXIT_SUCCESS) { Terminal::get().async_process(arguments, default_build_path, [this, arguments](int exit_status){ Terminal::get().async_print(arguments+" returned: "+std::to_string(exit_status)+'\n'); }); } }); } ProjectMarkDown::~ProjectMarkDown() { if(!last_temp_path.empty()) { boost::filesystem::remove(last_temp_path); last_temp_path=boost::filesystem::path(); } } void ProjectMarkDown::compile_and_run() { if(!last_temp_path.empty()) { boost::filesystem::remove(last_temp_path); last_temp_path=boost::filesystem::path(); } std::stringstream stdin_stream, stdout_stream; auto exit_status=Terminal::get().process(stdin_stream, stdout_stream, "markdown "+file_path.string(), this->file_path.parent_path()); if(exit_status==0) { boost::system::error_code ec; auto temp_path=boost::filesystem::temp_directory_path(ec); if(!ec) { temp_path/=boost::filesystem::unique_path(); temp_path+=".html"; if(!boost::filesystem::exists(temp_path)) { last_temp_path=temp_path; std::ofstream file_stream(temp_path.string(), std::fstream::binary); file_stream << stdout_stream.rdbuf(); file_stream.close(); Terminal::get().async_process("open "+temp_path.string()); } } } }