diff --git a/CMakeLists.txt b/CMakeLists.txt index aea8d33e..a1089d53 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -130,6 +130,7 @@ set(XEUS_CPP_SRC src/xinterpreter.cpp src/xoptions.cpp src/xparser.cpp + src/xutils.cpp ) if(EMSCRIPTEN) diff --git a/include/xeus-cpp/xbuffer.hpp b/include/xeus-cpp/xbuffer.hpp index 8d46a108..2833cf41 100644 --- a/include/xeus-cpp/xbuffer.hpp +++ b/include/xeus-cpp/xbuffer.hpp @@ -52,7 +52,7 @@ namespace xcpp { std::lock_guard lock(m_mutex); // Called for a string of characters. - m_output.append(s, count); + m_output.append(s, static_cast(count)); return count; } diff --git a/include/xeus-cpp/xutils.hpp b/include/xeus-cpp/xutils.hpp new file mode 100644 index 00000000..4df8a8fb --- /dev/null +++ b/include/xeus-cpp/xutils.hpp @@ -0,0 +1,37 @@ +/************************************************************************************ + * Copyright (c) 2023, xeus-cpp contributors * + * * + * Distributed under the terms of the BSD 3-Clause License. * + * * + * The full license is in the file LICENSE, distributed with this software. * + ************************************************************************************/ + +#ifndef XEUS_CPP_UTILS_HPP +#define XEUS_CPP_UTILS_HPP + +#include "xinterpreter.hpp" + +using interpreter_ptr = std::unique_ptr; + +namespace xcpp +{ + +#ifdef __GNUC__ + XEUS_CPP_API + void handler(int sig); +#endif + + XEUS_CPP_API + void stop_handler(int sig); + + XEUS_CPP_API + bool should_print_version(int argc, char* argv[]); + + XEUS_CPP_API + std::string extract_filename(int &argc, char* argv[]); + + XEUS_CPP_API + interpreter_ptr build_interpreter(int argc, char** argv); +} + +#endif diff --git a/src/main.cpp b/src/main.cpp index 8ebd0611..83f6f73f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -27,81 +27,11 @@ #include "xeus-cpp/xeus_cpp_config.hpp" #include "xeus-cpp/xinterpreter.hpp" - -#ifdef __GNUC__ -void handler(int sig) -{ - void* array[10]; - - // get void*'s for all entries on the stack - std::size_t size = backtrace(array, 10); - - // print out all the frames to stderr - fprintf(stderr, "Error: signal %d:\n", sig); - backtrace_symbols_fd(array, size, STDERR_FILENO); - exit(1); -} -#endif - -void stop_handler(int /*sig*/) -{ - exit(0); -} - -bool should_print_version(int argc, char* argv[]) -{ - for (int i = 0; i < argc; ++i) - { - if (std::string(argv[i]) == "--version") - { - return true; - } - } - return false; -} - -std::string extract_filename(int argc, char* argv[]) -{ - std::string res = ""; - for (int i = 0; i < argc; ++i) - { - if ((std::string(argv[i]) == "-f") && (i + 1 < argc)) - { - res = argv[i + 1]; - for (int j = i; j < argc - 2; ++j) - { - argv[j] = argv[j + 2]; - } - argc -= 2; - break; - } - } - return res; -} - -using interpreter_ptr = std::unique_ptr; - -interpreter_ptr build_interpreter(int argc, char** argv) -{ - int interpreter_argc = argc; // + 1; // ... - const char** interpreter_argv = new const char*[interpreter_argc]; - interpreter_argv[0] = "xeus-cpp"; - // Copy all arguments in the new array excepting the process name. - for (int i = 1; i < argc; i++) - { - interpreter_argv[i] = argv[i]; - } - // std::string include_dir = std::string(LLVM_DIR) + std::string("/include"); // ... - // interpreter_argv[interpreter_argc - 1] = include_dir.c_str(); // ... - - interpreter_ptr interp_ptr = interpreter_ptr(new xcpp::interpreter(interpreter_argc, interpreter_argv)); - delete[] interpreter_argv; - return interp_ptr; -} +#include "xeus-cpp/xutils.hpp" int main(int argc, char* argv[]) { - if (should_print_version(argc, argv)) + if (xcpp::should_print_version(argc, argv)) { std::clog << "xcpp " << XEUS_CPP_VERSION << std::endl; return 0; @@ -120,16 +50,16 @@ int main(int argc, char* argv[]) // Registering SIGSEGV handler #ifdef __GNUC__ std::clog << "registering handler for SIGSEGV" << std::endl; - signal(SIGSEGV, handler); + signal(SIGSEGV, xcpp::handler); // Registering SIGINT and SIGKILL handlers - signal(SIGKILL, stop_handler); + signal(SIGKILL, xcpp::stop_handler); #endif - signal(SIGINT, stop_handler); + signal(SIGINT, xcpp::stop_handler); - std::string file_name = extract_filename(argc, argv); + std::string file_name = xcpp::extract_filename(argc, argv); - interpreter_ptr interpreter = build_interpreter(argc, argv); + interpreter_ptr interpreter = xcpp::build_interpreter(argc, argv); auto context = xeus::make_context(); diff --git a/src/xutils.cpp b/src/xutils.cpp new file mode 100644 index 00000000..d8c44d78 --- /dev/null +++ b/src/xutils.cpp @@ -0,0 +1,99 @@ +/************************************************************************************ + * Copyright (c) 2023, xeus-cpp contributors * + * * + * Distributed under the terms of the BSD 3-Clause License. * + * * + * The full license is in the file LICENSE, distributed with this software. * + ************************************************************************************/ + +#include +#include +#include +#include + +#include + +#ifdef __GNUC__ +#include +#ifndef XEUS_CPP_EMSCRIPTEN_WASM_BUILD +#include +#endif +#include +#include +#endif + + +#include "xeus-cpp/xutils.hpp" +#include "xeus-cpp/xinterpreter.hpp" + +namespace xcpp +{ + +#if defined(__GNUC__) && !defined(XEUS_CPP_EMSCRIPTEN_WASM_BUILD) + void handler(int sig) + { + void* array[10]; + + // get void*'s for all entries on the stack + std::size_t size = backtrace(array, 10); + + // print out all the frames to stderr + fprintf(stderr, "Error: signal %d:\n", sig); + backtrace_symbols_fd(array, size, STDERR_FILENO); + exit(1); + } +#endif + + void stop_handler(int /*sig*/) + { + exit(0); + } + + bool should_print_version(int argc, char* argv[]) + { + for (int i = 0; i < argc; ++i) + { + if (std::string(argv[i]) == "--version") + { + return true; + } + } + return false; + } + + std::string extract_filename(int &argc, char* argv[]) + { + std::string res = ""; + for (int i = 0; i < argc; ++i) + { + if ((std::string(argv[i]) == "-f") && (i + 1 < argc)) + { + res = argv[i + 1]; + for (int j = i; j < argc - 2; ++j) + { + argv[j] = argv[j + 2]; + } + argc -= 2; + break; + } + } + return res; + } + + interpreter_ptr build_interpreter(int argc, char** argv) + { + int interpreter_argc = argc; // + 1; + const char** interpreter_argv = new const char*[interpreter_argc]; + interpreter_argv[0] = "xeus-cpp"; + // Copy all arguments in the new array excepting the process name. + for (int i = 1; i < argc; i++) + { + interpreter_argv[i] = argv[i]; + } + + interpreter_ptr interp_ptr = std::make_unique(interpreter_argc, interpreter_argv); + delete[] interpreter_argv; + return interp_ptr; + } + +} \ No newline at end of file diff --git a/test/test_interpreter.cpp b/test/test_interpreter.cpp index a14903fa..392b58d9 100644 --- a/test/test_interpreter.cpp +++ b/test/test_interpreter.cpp @@ -8,6 +8,7 @@ #include "doctest/doctest.h" #include "xeus-cpp/xinterpreter.hpp" +#include "xeus-cpp/xutils.hpp" TEST_SUITE("execute_request") { @@ -33,4 +34,17 @@ TEST_SUITE("execute_request") REQUIRE(result["found"] == true); REQUIRE(result["status"] == "ok"); } -} \ No newline at end of file +} + +TEST_SUITE("extract_filename") +{ + TEST_CASE("extract_filename_basic_test") + { + const char* arguments[] = {"argument1", "-f", "filename.txt", "argument4"}; + int argc = sizeof(arguments) / sizeof(arguments[0]); + + std::string result = xcpp::extract_filename(argc, const_cast(arguments)); + REQUIRE(result == "filename.txt"); + REQUIRE(argc == 2); + } +}