add error class

self-hosting
MoAlyousef 4 years ago
parent b24df8406e
commit a6239fd335

@ -10,7 +10,7 @@ AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: false AllowShortFunctionsOnASingleLine: true
AllowShortIfStatementsOnASingleLine: false AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None AlwaysBreakAfterDefinitionReturnType: None

@ -2,7 +2,6 @@ cmake_minimum_required(VERSION 3.14)
project(cmkr VERSION 0.1.0) project(cmkr VERSION 0.1.0)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMKRLIB_SOURCES set(CMKRLIB_SOURCES
@ -10,6 +9,7 @@ set(CMKRLIB_SOURCES
"src/gen.cpp" "src/gen.cpp"
"src/help.cpp" "src/help.cpp"
"src/build.cpp" "src/build.cpp"
"src/error.cpp"
) )
add_library(cmkrlib STATIC ${CMKRLIB_SOURCES}) add_library(cmkrlib STATIC ${CMKRLIB_SOURCES})

@ -40,7 +40,7 @@ version = "0.1.0"
[[bin]] [[bin]]
name = "cmkrlib" name = "cmkrlib"
type = "static" 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"] include-dirs = ["vendor"]
features = ["cxx_std_17"] features = ["cxx_std_17"]

@ -8,7 +8,7 @@ version = "0.1.0"
[[bin]] [[bin]]
name = "cmkrlib" name = "cmkrlib"
type = "static" 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"] include-dirs = ["vendor"]
features = ["cxx_std_17"] features = ["cxx_std_17"]

@ -3,6 +3,7 @@
#include "gen.h" #include "gen.h"
#include "help.h" #include "help.h"
#include <exception>
#include <filesystem> #include <filesystem>
#include <stdexcept> #include <stdexcept>
#include <string> #include <string>
@ -15,25 +16,29 @@ const char *handle_args(int argc, char **argv) {
args.push_back(argv[i]); args.push_back(argv[i]);
if (args.size() < 2) 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]; std::string main_arg = args[1];
if (main_arg == "gen") { if (main_arg == "gen") {
cmkr::gen::generate_cmake(std::filesystem::current_path().string().c_str()); auto ret = cmkr::gen::generate_cmake(std::filesystem::current_path().string().c_str());
return "Generation successful!"; if (ret)
return "CMake generation error!";
return "CMake generation successful!";
} else if (main_arg == "help") { } else if (main_arg == "help") {
return cmkr::help::message(); return cmkr::help::message();
} else if (main_arg == "version") { } else if (main_arg == "version") {
return cmkr::help::version(); return cmkr::help::version();
} else if (main_arg == "init") { } else if (main_arg == "init") {
if (args.size() < 3) if (args.size() < 3)
throw std::runtime_error("Please provide a project type!"); return "Please provide a project type!";
cmkr::gen::generate_project(args[2].c_str()); auto ret = cmkr::gen::generate_project(args[2].c_str());
if (ret)
return "Initialization failure!";
return "Directory initialized!"; return "Directory initialized!";
} else if (main_arg == "build") { } else if (main_arg == "build") {
auto ret = build::run(argc, argv); auto ret = build::run(argc, argv);
if (ret) if (ret)
return "Run faced an error!"; return "CMake build error!";
return "Run completed!"; return "CMake run completed!";
} else { } else {
return "Unknown argument!"; return "Unknown argument!";
} }
@ -41,5 +46,11 @@ const char *handle_args(int argc, char **argv) {
} // namespace cmkr::args } // namespace cmkr::args
const char *cmkr_args_handle_args(int argc, char **argv) { const char *cmkr_args_handle_args(int argc, char **argv) {
try {
return cmkr::args::handle_args(argc, argv); return cmkr::args::handle_args(argc, argv);
} catch (const std::exception &e) {
return e.what();
} catch (...) {
return nullptr;
}
} }

@ -1,4 +1,5 @@
#include "build.h" #include "build.h"
#include "error.h"
#include <filesystem> #include <filesystem>
#include <sstream> #include <sstream>
@ -47,5 +48,9 @@ int run(int argc, char **argv) {
} // namespace cmkr::build } // namespace cmkr::build
int cmkr_build_run(int argc, char **argv) { int cmkr_build_run(int argc, char **argv) {
try {
return cmkr::build::run(argc, argv); return cmkr::build::run(argc, argv);
} catch (...) {
return cmkr::error::Status(cmkr::error::Status::Code::BuildError);
}
} }

@ -0,0 +1,20 @@
#include "error.h"
#include <assert.h>
namespace cmkr::error {
Status::Status(Code ec) noexcept : ec_(ec) {}
Status::operator int() noexcept { return static_cast<int>(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];
}

@ -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

@ -1,4 +1,5 @@
#include "gen.h" #include "gen.h"
#include "error.h"
#include <filesystem> #include <filesystem>
#include <fstream> #include <fstream>
@ -25,7 +26,7 @@ inline std::string to_upper(const std::string &str) {
} // namespace detail } // namespace detail
void generate_project(const char *str) { int generate_project(const char *str) {
fs::create_directory("src"); fs::create_directory("src");
auto dir_name = fs::current_path().stem(); auto dir_name = fs::current_path().stem();
if (!strcmp(str, "exe")) { if (!strcmp(str, "exe")) {
@ -39,8 +40,7 @@ void generate_project(const char *str) {
std::ofstream ofs2("cmake.toml"); std::ofstream ofs2("cmake.toml");
if (ofs2.is_open()) { if (ofs2.is_open()) {
ofs2 << "[cmake]\nminimum = \"3.14\"\n\n[project]\nname = \"" ofs2 << "[cmake]\nminimum = \"3.14\"\n\n[project]\nname = \"" << dir_name.string()
<< dir_name.string()
<< "\"\nversion = " << "\"\nversion = "
"\"0.1.0\"\n\n[[bin]]\nname = \"" "\"0.1.0\"\n\n[[bin]]\nname = \""
<< dir_name.string() << "\"\nsources = [\"src/main.cpp\"]\ntype = \"" << str << dir_name.string() << "\"\nsources = [\"src/main.cpp\"]\ntype = \"" << str
@ -58,8 +58,7 @@ void generate_project(const char *str) {
std::ofstream ofs2("cmake.toml"); std::ofstream ofs2("cmake.toml");
if (ofs2.is_open()) { if (ofs2.is_open()) {
ofs2 << "[cmake]\nminimum = \"3.14\"\n\n[project]\nname = \"" ofs2 << "[cmake]\nminimum = \"3.14\"\n\n[project]\nname = \"" << dir_name.string()
<< dir_name.string()
<< "\"\nversion = " << "\"\nversion = "
"\"0.1.0\"\n\n[[bin]]\nname = \"" "\"0.1.0\"\n\n[[bin]]\nname = \""
<< dir_name.string() << "\"\nsources = [\"src/lib.cpp\"]\ntype = \"" << str << dir_name.string() << "\"\nsources = [\"src/lib.cpp\"]\ntype = \"" << str
@ -70,9 +69,10 @@ void generate_project(const char *str) {
} else { } else {
throw std::runtime_error("Unknown project type. Types are exe, shared, static!"); 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::stringstream ss;
std::vector<std::string> subdirs; std::vector<std::string> subdirs;
@ -83,30 +83,30 @@ void generate_cmake(const char *path) {
ss << "cmake_minimum_required(VERSION " << cmake_min << ")\n\n"; ss << "cmake_minimum_required(VERSION " << cmake_min << ")\n\n";
if (cmake.contains("cpp-flags")) { 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(); const auto flags = toml::find(cmake, "cpp-flags").as_array();
for (const auto &flag : flags) { for (const auto &flag : flags) {
ss << " " << flag; ss << " " << std::string(flag.as_string());
} }
ss << ")\n\n"; ss << "\")\n\n";
} }
if (cmake.contains("c-flags")) { 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(); const auto flags = toml::find(cmake, "c-flags").as_array();
for (const auto &flag : flags) { for (const auto &flag : flags) {
ss << " " << flag; ss << " " << std::string(flag.as_string());
} }
ss << ")\n\n"; ss << "\")\n\n";
} }
if (cmake.contains("link-flags")) { 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(); const auto flags = toml::find(cmake, "link-flags").as_array();
for (const auto &flag : flags) { for (const auto &flag : flags) {
ss << " " << flag; ss << " " << std::string(flag.as_string());
} }
ss << ")\n\n"; ss << "\")\n\n";
} }
if (cmake.contains("subdirs")) { if (cmake.contains("subdirs")) {
@ -142,7 +142,8 @@ void generate_cmake(const char *path) {
if (toml.contains("fetch-content")) { if (toml.contains("fetch-content")) {
std::map<std::string, std::map<std::string, std::string>> deps = std::map<std::string, std::map<std::string, std::string>> deps =
toml::find<std::map<std::string, std::map<std::string, std::string>>>(toml, "fetch-content"); toml::find<std::map<std::string, std::map<std::string, std::string>>>(toml,
"fetch-content");
ss << "include(FetchContent)\n\n"; ss << "include(FetchContent)\n\n";
for (const auto &dep : deps) { for (const auto &dep : deps) {
ss << "FetchContent_Declare(\n\t" << dep.first << "\n"; ss << "FetchContent_Declare(\n\t" << dep.first << "\n";
@ -154,7 +155,7 @@ void generate_cmake(const char *path) {
} }
} }
ss << "\nset(CMAKE_EXPORT_COMPILE_COMMANDS ON)\n\n"; ss << "set(CMAKE_EXPORT_COMPILE_COMMANDS ON)\n\n";
if (toml.contains("bin")) { if (toml.contains("bin")) {
const auto &bins = toml::find(toml, "bin").as_array(); const auto &bins = toml::find(toml, "bin").as_array();
@ -233,13 +234,22 @@ void generate_cmake(const char *path) {
for (const auto &sub : subdirs) { for (const auto &sub : subdirs) {
generate_cmake(sub.c_str()); generate_cmake(sub.c_str());
} }
return 0;
} }
} // namespace cmkr::gen } // namespace cmkr::gen
void cmkr_gen_generate_project(const char *typ) { int cmkr_gen_generate_project(const char *typ) {
cmkr::gen::generate_project(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) { int cmkr_gen_generate_cmake(const char *path) {
cmkr::gen::generate_cmake(path); try {
return cmkr::gen::generate_cmake(path);
} catch (...) {
return cmkr::error::Status(cmkr::error::Status::Code::GenerationError);
}
} }

@ -3,18 +3,18 @@
#ifdef __cplusplus #ifdef __cplusplus
namespace cmkr::gen { 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 } // namespace cmkr::gen
extern "C" { extern "C" {
#endif #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 #ifdef __cplusplus
} }

@ -2,11 +2,9 @@
namespace cmkr::help { namespace cmkr::help {
const char *version() { const char *version() noexcept { return "cmkr version 0.1.0"; }
return "cmkr version 0.1.0";
}
const char *message() { const char *message() noexcept {
return R"lit( return R"lit(
Usage: cmkr [arguments] Usage: cmkr [arguments]
arguments: arguments:
@ -19,10 +17,6 @@ arguments:
} }
} // namespace cmkr::help } // namespace cmkr::help
const char *cmkr_help_version(void) { const char *cmkr_help_version(void) { return cmkr::help::version(); }
return cmkr::help::version();
}
const char *cmkr_help_message(void) { const char *cmkr_help_message(void) { return cmkr::help::message(); }
return cmkr::help::message();
}

@ -3,9 +3,9 @@
#ifdef __cplusplus #ifdef __cplusplus
namespace cmkr::help { namespace cmkr::help {
const char *version(); const char *version() noexcept;
const char *message(); const char *message() noexcept;
} // namespace cmkr::help } // namespace cmkr::help

Loading…
Cancel
Save