diff --git a/.clang-format b/.clang-format index 66a8eb5..f833c75 100644 --- a/.clang-format +++ b/.clang-format @@ -10,7 +10,7 @@ AlignTrailingComments: true AllowAllParametersOfDeclarationOnNextLine: true AllowShortBlocksOnASingleLine: false AllowShortCaseLabelsOnASingleLine: false -AllowShortFunctionsOnASingleLine: false +AllowShortFunctionsOnASingleLine: true AllowShortIfStatementsOnASingleLine: false AllowShortLoopsOnASingleLine: false AlwaysBreakAfterDefinitionReturnType: None diff --git a/CMakeLists.txt b/CMakeLists.txt index cb5bc65..e7cc724 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,6 @@ cmake_minimum_required(VERSION 3.14) project(cmkr VERSION 0.1.0) - set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMKRLIB_SOURCES @@ -10,6 +9,7 @@ set(CMKRLIB_SOURCES "src/gen.cpp" "src/help.cpp" "src/build.cpp" + "src/error.cpp" ) add_library(cmkrlib STATIC ${CMKRLIB_SOURCES}) diff --git a/README.md b/README.md index 741f327..23e299f 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ version = "0.1.0" [[bin]] name = "cmkrlib" type = "static" -sources = ["src/args.cpp", "src/gen.cpp", "src/help.cpp", "src/build.cpp"] +sources = ["src/args.cpp", "src/gen.cpp", "src/help.cpp", "src/build.cpp", "error.cpp"] include-dirs = ["vendor"] features = ["cxx_std_17"] diff --git a/cmake.toml b/cmake.toml index d6446c6..aaabc42 100644 --- a/cmake.toml +++ b/cmake.toml @@ -8,7 +8,7 @@ version = "0.1.0" [[bin]] name = "cmkrlib" type = "static" -sources = ["src/args.cpp", "src/gen.cpp", "src/help.cpp", "src/build.cpp"] +sources = ["src/args.cpp", "src/gen.cpp", "src/help.cpp", "src/build.cpp", "src/error.cpp"] include-dirs = ["vendor"] features = ["cxx_std_17"] diff --git a/src/args.cpp b/src/args.cpp index 0337068..ffb8002 100644 --- a/src/args.cpp +++ b/src/args.cpp @@ -3,6 +3,7 @@ #include "gen.h" #include "help.h" +#include #include #include #include @@ -15,25 +16,29 @@ const char *handle_args(int argc, char **argv) { args.push_back(argv[i]); if (args.size() < 2) - throw std::runtime_error("Please provide command line arguments!"); + return "Please provide command line arguments!"; std::string main_arg = args[1]; if (main_arg == "gen") { - cmkr::gen::generate_cmake(std::filesystem::current_path().string().c_str()); - return "Generation successful!"; + auto ret = cmkr::gen::generate_cmake(std::filesystem::current_path().string().c_str()); + if (ret) + return "CMake generation error!"; + return "CMake generation successful!"; } else if (main_arg == "help") { return cmkr::help::message(); } else if (main_arg == "version") { return cmkr::help::version(); } else if (main_arg == "init") { if (args.size() < 3) - throw std::runtime_error("Please provide a project type!"); - cmkr::gen::generate_project(args[2].c_str()); + return "Please provide a project type!"; + auto ret = cmkr::gen::generate_project(args[2].c_str()); + if (ret) + return "Initialization failure!"; return "Directory initialized!"; } else if (main_arg == "build") { auto ret = build::run(argc, argv); if (ret) - return "Run faced an error!"; - return "Run completed!"; + return "CMake build error!"; + return "CMake run completed!"; } else { return "Unknown argument!"; } @@ -41,5 +46,11 @@ const char *handle_args(int argc, char **argv) { } // namespace cmkr::args const char *cmkr_args_handle_args(int argc, char **argv) { - return cmkr::args::handle_args(argc, argv); + try { + return cmkr::args::handle_args(argc, argv); + } catch (const std::exception &e) { + return e.what(); + } catch (...) { + return nullptr; + } } diff --git a/src/build.cpp b/src/build.cpp index 3ecbf90..7a91f5b 100644 --- a/src/build.cpp +++ b/src/build.cpp @@ -1,4 +1,5 @@ #include "build.h" +#include "error.h" #include #include @@ -47,5 +48,9 @@ int run(int argc, char **argv) { } // namespace cmkr::build int cmkr_build_run(int argc, char **argv) { - return cmkr::build::run(argc, argv); + try { + return cmkr::build::run(argc, argv); + } catch (...) { + return cmkr::error::Status(cmkr::error::Status::Code::BuildError); + } } \ No newline at end of file diff --git a/src/error.cpp b/src/error.cpp new file mode 100644 index 0000000..1a3038f --- /dev/null +++ b/src/error.cpp @@ -0,0 +1,20 @@ +#include "error.h" + +#include + +namespace cmkr::error { + +Status::Status(Code ec) noexcept : ec_(ec) {} + +Status::operator int() noexcept { return static_cast(ec_); } + +} // namespace cmkr::error + +const char *err_string[] = { + "Success", "Runtime error", "Initialization error", "CMake generation error", "Build error", +}; + +const char *cmkr_error_status(int i) { + assert(i >= 0 && i < 5); + return err_string[i]; +} \ No newline at end of file diff --git a/src/error.h b/src/error.h new file mode 100644 index 0000000..89fe5bd --- /dev/null +++ b/src/error.h @@ -0,0 +1,31 @@ +#pragma once + +#ifdef __cplusplus +namespace cmkr::error { + +struct Status { + enum class Code { + Success = 0, + RuntimeError, + InitError, + GenerationError, + BuildError, + }; + Status() = delete; + Status(Code ec) noexcept; + operator int() noexcept; + + private: + Code ec_; +}; + +} // namespace cmkr::error + +extern "C" { +#endif + +const char *cmkr_error_status(int); + +#ifdef __cplusplus +} +#endif diff --git a/src/gen.cpp b/src/gen.cpp index d6870b4..1a448f5 100644 --- a/src/gen.cpp +++ b/src/gen.cpp @@ -1,4 +1,5 @@ #include "gen.h" +#include "error.h" #include #include @@ -25,7 +26,7 @@ inline std::string to_upper(const std::string &str) { } // namespace detail -void generate_project(const char *str) { +int generate_project(const char *str) { fs::create_directory("src"); auto dir_name = fs::current_path().stem(); if (!strcmp(str, "exe")) { @@ -39,8 +40,7 @@ void generate_project(const char *str) { std::ofstream ofs2("cmake.toml"); if (ofs2.is_open()) { - ofs2 << "[cmake]\nminimum = \"3.14\"\n\n[project]\nname = \"" - << dir_name.string() + ofs2 << "[cmake]\nminimum = \"3.14\"\n\n[project]\nname = \"" << dir_name.string() << "\"\nversion = " "\"0.1.0\"\n\n[[bin]]\nname = \"" << dir_name.string() << "\"\nsources = [\"src/main.cpp\"]\ntype = \"" << str @@ -58,8 +58,7 @@ void generate_project(const char *str) { std::ofstream ofs2("cmake.toml"); if (ofs2.is_open()) { - ofs2 << "[cmake]\nminimum = \"3.14\"\n\n[project]\nname = \"" - << dir_name.string() + ofs2 << "[cmake]\nminimum = \"3.14\"\n\n[project]\nname = \"" << dir_name.string() << "\"\nversion = " "\"0.1.0\"\n\n[[bin]]\nname = \"" << dir_name.string() << "\"\nsources = [\"src/lib.cpp\"]\ntype = \"" << str @@ -70,9 +69,10 @@ void generate_project(const char *str) { } else { throw std::runtime_error("Unknown project type. Types are exe, shared, static!"); } + return 0; } -void generate_cmake(const char *path) { +int generate_cmake(const char *path) { std::stringstream ss; std::vector subdirs; @@ -83,30 +83,30 @@ void generate_cmake(const char *path) { ss << "cmake_minimum_required(VERSION " << cmake_min << ")\n\n"; if (cmake.contains("cpp-flags")) { - ss << "set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}"; + ss << "set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}\""; const auto flags = toml::find(cmake, "cpp-flags").as_array(); for (const auto &flag : flags) { - ss << " " << flag; + ss << " " << std::string(flag.as_string()); } - ss << ")\n\n"; + ss << "\")\n\n"; } if (cmake.contains("c-flags")) { - ss << "set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS}"; + ss << "set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS}\""; const auto flags = toml::find(cmake, "c-flags").as_array(); for (const auto &flag : flags) { - ss << " " << flag; + ss << " " << std::string(flag.as_string()); } - ss << ")\n\n"; + ss << "\")\n\n"; } if (cmake.contains("link-flags")) { - ss << "set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS}"; + ss << "set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS}\""; const auto flags = toml::find(cmake, "link-flags").as_array(); for (const auto &flag : flags) { - ss << " " << flag; + ss << " " << std::string(flag.as_string()); } - ss << ")\n\n"; + ss << "\")\n\n"; } if (cmake.contains("subdirs")) { @@ -142,19 +142,20 @@ void generate_cmake(const char *path) { if (toml.contains("fetch-content")) { std::map> deps = - toml::find>>(toml, "fetch-content"); + toml::find>>(toml, + "fetch-content"); ss << "include(FetchContent)\n\n"; for (const auto &dep : deps) { ss << "FetchContent_Declare(\n\t" << dep.first << "\n"; - for (const auto &arg: dep.second) { + for (const auto &arg : dep.second) { ss << "\t" << arg.first << " " << arg.second << "\n"; } ss << "\t)\n\n" - << "FetchContent_MakeAvailable("<< dep.first << ")\n\n"; + << "FetchContent_MakeAvailable(" << dep.first << ")\n\n"; } } - ss << "\nset(CMAKE_EXPORT_COMPILE_COMMANDS ON)\n\n"; + ss << "set(CMAKE_EXPORT_COMPILE_COMMANDS ON)\n\n"; if (toml.contains("bin")) { const auto &bins = toml::find(toml, "bin").as_array(); @@ -233,13 +234,22 @@ void generate_cmake(const char *path) { for (const auto &sub : subdirs) { generate_cmake(sub.c_str()); } + return 0; } } // namespace cmkr::gen -void cmkr_gen_generate_project(const char *typ) { - cmkr::gen::generate_project(typ); +int cmkr_gen_generate_project(const char *typ) { + try { + return cmkr::gen::generate_project(typ); + } catch (...) { + return cmkr::error::Status(cmkr::error::Status::Code::InitError); + } } -void cmkr_gen_generate_cmake(const char *path) { - cmkr::gen::generate_cmake(path); +int cmkr_gen_generate_cmake(const char *path) { + try { + return cmkr::gen::generate_cmake(path); + } catch (...) { + return cmkr::error::Status(cmkr::error::Status::Code::GenerationError); + } } diff --git a/src/gen.h b/src/gen.h index 0ef6bc2..9fdf6ca 100644 --- a/src/gen.h +++ b/src/gen.h @@ -3,18 +3,18 @@ #ifdef __cplusplus namespace cmkr::gen { -void generate_project(const char *typ); +int generate_project(const char *typ); -void generate_cmake(const char *path); +int generate_cmake(const char *path); } // namespace cmkr::gen extern "C" { #endif -void cmkr_gen_generate_project(const char *typ); +int cmkr_gen_generate_project(const char *typ); -void cmkr_gen_generate_cmake(const char *path); +int cmkr_gen_generate_cmake(const char *path); #ifdef __cplusplus } diff --git a/src/help.cpp b/src/help.cpp index 445b677..b7bc8e1 100644 --- a/src/help.cpp +++ b/src/help.cpp @@ -2,11 +2,9 @@ namespace cmkr::help { -const char *version() { - return "cmkr version 0.1.0"; -} +const char *version() noexcept { return "cmkr version 0.1.0"; } -const char *message() { +const char *message() noexcept { return R"lit( Usage: cmkr [arguments] arguments: @@ -19,10 +17,6 @@ arguments: } } // namespace cmkr::help -const char *cmkr_help_version(void) { - return cmkr::help::version(); -} +const char *cmkr_help_version(void) { return cmkr::help::version(); } -const char *cmkr_help_message(void) { - return cmkr::help::message(); -} \ No newline at end of file +const char *cmkr_help_message(void) { return cmkr::help::message(); } \ No newline at end of file diff --git a/src/help.h b/src/help.h index 4cece36..1be4374 100644 --- a/src/help.h +++ b/src/help.h @@ -3,9 +3,9 @@ #ifdef __cplusplus namespace cmkr::help { -const char *version(); +const char *version() noexcept; -const char *message(); +const char *message() noexcept; } // namespace cmkr::help