diff --git a/src/applib/CMakeLists.txt b/src/applib/CMakeLists.txt index 3ffc368..19efec7 100644 --- a/src/applib/CMakeLists.txt +++ b/src/applib/CMakeLists.txt @@ -66,6 +66,7 @@ target_link_libraries(applib libdebug hz rconfig + boost_leaf app_gtkmm_interface app_pcrecpp_interface app_gettext_interface diff --git a/src/applib/smartctl_parser.cpp b/src/applib/smartctl_parser.cpp index ae842ce..691b27a 100644 --- a/src/applib/smartctl_parser.cpp +++ b/src/applib/smartctl_parser.cpp @@ -33,18 +33,23 @@ std::unique_ptr SmartctlParser::create(SmartctlParserType type) -// std::optional SmartctlParser::detect_output_type(const std::string& output) const -// { +leaf::result SmartctlParser::detect_output_type(const std::string& output) +{ // Look for the first non-whitespace symbol - // auto first_symbol = std::find_if(output.begin(), output.end(), [&](char c) { - // return !std::isspace(c, std::locale::classic()); - // }); - // if (first_symbol != output.end() && *first_symbol == '-' - - - - -// } + auto first_symbol = std::find_if(output.begin(), output.end(), [&](char c) { + return !std::isspace(c, std::locale::classic()); + }); + if (first_symbol != output.end()) { + if (*first_symbol == '{') { + return SmartctlParserType::Json; + } + if (output.rfind("smartctl", static_cast(first_symbol - output.begin())) == 0) { + return SmartctlParserType::Text; + } + return leaf::new_error(SmartctlParserError::UnsupportedFormat); + } + return leaf::new_error(SmartctlParserError::EmptyInput); +} diff --git a/src/applib/smartctl_parser.h b/src/applib/smartctl_parser.h index 594075c..02b2142 100644 --- a/src/applib/smartctl_parser.h +++ b/src/applib/smartctl_parser.h @@ -16,12 +16,19 @@ Copyright: #include #include -// #include "leaf_ns.h" +#include "leaf_ns.h" #include "ata_storage_property.h" #include "smartctl_parser_types.h" +enum class SmartctlParserError { + EmptyInput, + UnsupportedFormat, +}; + + + /// Smartctl (S)ATA text output parser. /// Note: ALL parse_* functions (except parse_full() and parse_version()) /// expect data in unix-newline format! @@ -66,7 +73,7 @@ class SmartctlParser { /// Detect smartctl output type (text, json). - // [[nodiscard]] leaf::result detect_output_type(const std::string& output) const; + [[nodiscard]] static leaf::result detect_output_type(const std::string& output); /// Get "full" data, as passed to parse_full(). diff --git a/src/applib/tests/CMakeLists.txt b/src/applib/tests/CMakeLists.txt index dbc4f46..5449f42 100644 --- a/src/applib/tests/CMakeLists.txt +++ b/src/applib/tests/CMakeLists.txt @@ -15,6 +15,7 @@ endif() add_library(applib_tests OBJECT) target_sources(applib_tests PRIVATE test_app_pcrecpp.cpp + test_smartctl_parser.cpp test_smartctl_version_parser.cpp ) target_link_libraries(applib_tests PRIVATE diff --git a/src/applib/tests/test_smartctl_parser.cpp b/src/applib/tests/test_smartctl_parser.cpp new file mode 100644 index 0000000..6bf20ce --- /dev/null +++ b/src/applib/tests/test_smartctl_parser.cpp @@ -0,0 +1,53 @@ +/****************************************************************************** +License: BSD Zero Clause License +Copyright: + (C) 2022 Alexander Shaduri +******************************************************************************/ +/// \file +/// \author Alexander Shaduri +/// \ingroup applib_tests +/// \weakgroup applib_tests +/// @{ + +// Catch2 v3 +//#include "catch2/catch_test_macros.hpp" + +// Catch2 v2 +#include "catch2/catch.hpp" + +#include "test_helpers/test_helpers.h" +#include "applib/smartctl_parser.h" + + + +TEST_CASE("SmartctlFormatDetection", "[app][parser]") +{ + REQUIRE( try_expect_errors([] { + return SmartctlParser::detect_output_type({}); + }, SmartctlParserError::EmptyInput) ); + + REQUIRE( try_expect_errors([] { + return SmartctlParser::detect_output_type("smart"); + }, SmartctlParserError::UnsupportedFormat) ); + + REQUIRE(SmartctlParser::detect_output_type("{ }").value() == SmartctlParserType::Json); + + REQUIRE(SmartctlParser::detect_output_type(" \n { } ").value() == SmartctlParserType::Json); + + REQUIRE(SmartctlParser::detect_output_type("smartctl").value() == SmartctlParserType::Text); + + REQUIRE(SmartctlParser::detect_output_type( +R"(smartctl 7.2 2020-12-30 r5155 [x86_64-linux-5.3.18-lp152.66-default] (SUSE RPM) +Copyright (C) 2002-20, Bruce Allen, Christian Franke, www.smartmontools.org + +)").value() == SmartctlParserType::Text); + +} + + + +/// @} + + + +