Initial port from pcre to std::regex (not working yet).

This commit is contained in:
Alexander Shaduri
2024-05-16 16:27:18 +04:00
parent cf3a9f6ae3
commit 1df72dc2e0
4 changed files with 482 additions and 579 deletions
+147 -248
View File
@@ -12,12 +12,15 @@
#ifndef APP_REGEX_H
#define APP_REGEX_H
#include <cstddef>
#include <map>
#include <string>
#include <string_view>
#include <vector>
#include <regex>
#include "hz/debug.h"
#include "hz/string_algo.h"
/**
@@ -68,6 +71,9 @@ inline std::regex app_regex_re(const std::string& perl_pattern)
}
/// Partially match a string against a regular expression.
/// \return true if a match was found.
inline bool app_regex_partial_match(const std::regex& re, const std::string& str)
@@ -149,7 +155,6 @@ inline bool app_regex_partial_match(const char* perl_pattern, const std::string&
}
/// Partially match a string against a regular expression.
/// \return true if a match was found.
inline bool app_regex_partial_match(const std::regex& re, const std::string& str, std::vector<std::string*> matches_vector)
@@ -186,115 +191,155 @@ inline bool app_regex_partial_match(const char* perl_pattern, const std::string&
/*
/// Partially match a string against a regular expression.
/// matched_ptr arguments take pointers to std::string and arithmetical types,
/// and are filled with matched parts of `str.
/// \return true if a match was found.
inline bool app_pcre_match(const pcrecpp::RE& re, const std::string_view& str,
const pcrecpp::Arg& matched_ptr1 = pcrecpp::RE::no_arg,
const pcrecpp::Arg& matched_ptr2 = pcrecpp::RE::no_arg,
const pcrecpp::Arg& matched_ptr3 = pcrecpp::RE::no_arg,
const pcrecpp::Arg& matched_ptr4 = pcrecpp::RE::no_arg,
const pcrecpp::Arg& matched_ptr5 = pcrecpp::RE::no_arg,
const pcrecpp::Arg& matched_ptr6 = pcrecpp::RE::no_arg,
const pcrecpp::Arg& matched_ptr7 = pcrecpp::RE::no_arg,
const pcrecpp::Arg& matched_ptr8 = pcrecpp::RE::no_arg,
const pcrecpp::Arg& matched_ptr9 = pcrecpp::RE::no_arg,
const pcrecpp::Arg& matched_ptr10 = pcrecpp::RE::no_arg,
const pcrecpp::Arg& matched_ptr11 = pcrecpp::RE::no_arg,
const pcrecpp::Arg& matched_ptr12 = pcrecpp::RE::no_arg,
const pcrecpp::Arg& matched_ptr13 = pcrecpp::RE::no_arg,
const pcrecpp::Arg& matched_ptr14 = pcrecpp::RE::no_arg,
const pcrecpp::Arg& matched_ptr15 = pcrecpp::RE::no_arg,
const pcrecpp::Arg& matched_ptr16 = pcrecpp::RE::no_arg);
inline bool app_regex_full_match(const std::regex& re, const std::string& str)
{
return std::regex_match(str, re);
}
/// Partially match a string against a pattern in "/pattern/modifiers" format.
/// matched_ptr arguments take pointers to std::string and arithmetical types,
/// and are filled with matched parts of `str.
/// Partially match a string against a regular expression.
/// \return true if a match was found.
inline bool app_pcre_match(const std::string& perl_pattern, const std::string_view& str,
const pcrecpp::Arg& matched_ptr1 = pcrecpp::RE::no_arg,
const pcrecpp::Arg& matched_ptr2 = pcrecpp::RE::no_arg,
const pcrecpp::Arg& matched_ptr3 = pcrecpp::RE::no_arg,
const pcrecpp::Arg& matched_ptr4 = pcrecpp::RE::no_arg,
const pcrecpp::Arg& matched_ptr5 = pcrecpp::RE::no_arg,
const pcrecpp::Arg& matched_ptr6 = pcrecpp::RE::no_arg,
const pcrecpp::Arg& matched_ptr7 = pcrecpp::RE::no_arg,
const pcrecpp::Arg& matched_ptr8 = pcrecpp::RE::no_arg,
const pcrecpp::Arg& matched_ptr9 = pcrecpp::RE::no_arg,
const pcrecpp::Arg& matched_ptr10 = pcrecpp::RE::no_arg,
const pcrecpp::Arg& matched_ptr11 = pcrecpp::RE::no_arg,
const pcrecpp::Arg& matched_ptr12 = pcrecpp::RE::no_arg,
const pcrecpp::Arg& matched_ptr13 = pcrecpp::RE::no_arg,
const pcrecpp::Arg& matched_ptr14 = pcrecpp::RE::no_arg,
const pcrecpp::Arg& matched_ptr15 = pcrecpp::RE::no_arg,
const pcrecpp::Arg& matched_ptr16 = pcrecpp::RE::no_arg);
inline bool app_regex_full_match(const std::string& perl_pattern, const std::string& str)
{
return app_regex_full_match(app_regex_re(perl_pattern), str);
}
/// Match a string against a pattern in "/pattern/modifiers" format.
/// matched_ptr arguments take pointers to std::string and arithmetical types,
/// and are filled with matched parts of `str.
/// This overload is needed to avoid ambiguity with pcrecpp::RE overload.
/// Partially match a string against a regular expression.
/// \return true if a match was found.
inline bool app_pcre_match(const char* perl_pattern, const std::string_view& str,
const pcrecpp::Arg& matched_ptr1 = pcrecpp::RE::no_arg,
const pcrecpp::Arg& matched_ptr2 = pcrecpp::RE::no_arg,
const pcrecpp::Arg& matched_ptr3 = pcrecpp::RE::no_arg,
const pcrecpp::Arg& matched_ptr4 = pcrecpp::RE::no_arg,
const pcrecpp::Arg& matched_ptr5 = pcrecpp::RE::no_arg,
const pcrecpp::Arg& matched_ptr6 = pcrecpp::RE::no_arg,
const pcrecpp::Arg& matched_ptr7 = pcrecpp::RE::no_arg,
const pcrecpp::Arg& matched_ptr8 = pcrecpp::RE::no_arg,
const pcrecpp::Arg& matched_ptr9 = pcrecpp::RE::no_arg,
const pcrecpp::Arg& matched_ptr10 = pcrecpp::RE::no_arg,
const pcrecpp::Arg& matched_ptr11 = pcrecpp::RE::no_arg,
const pcrecpp::Arg& matched_ptr12 = pcrecpp::RE::no_arg,
const pcrecpp::Arg& matched_ptr13 = pcrecpp::RE::no_arg,
const pcrecpp::Arg& matched_ptr14 = pcrecpp::RE::no_arg,
const pcrecpp::Arg& matched_ptr15 = pcrecpp::RE::no_arg,
const pcrecpp::Arg& matched_ptr16 = pcrecpp::RE::no_arg);
inline bool app_regex_full_match(const char* perl_pattern, const std::string& str)
{
return app_regex_full_match(app_regex_re(perl_pattern), str);
}
/// Partially match a string against a regular expression.
/// \return true if a match was found.
inline bool app_regex_full_match(const std::regex& re, const std::string& str, std::smatch& matches)
{
return std::regex_match(str, matches, re);
}
/// Partially match a string against a regular expression.
/// \return true if a match was found.
inline bool app_regex_full_match(const std::string& perl_pattern, const std::string& str, std::smatch& matches)
{
return app_regex_full_match(app_regex_re(perl_pattern), str, matches);
}
/// Partially match a string against a regular expression.
/// \return true if a match was found.
inline bool app_regex_full_match(const char* perl_pattern, const std::string& str, std::smatch& matches)
{
return app_regex_full_match(app_regex_re(perl_pattern), str, matches);
}
/// Partially match a string against a regular expression.
/// \return true if a match was found.
inline bool app_regex_full_match(const std::regex& re, const std::string& str, std::string* first_submatch)
{
std::smatch matches;
if (!app_regex_full_match(re, str, matches) || matches.size() < 2) {
return false;
}
if (first_submatch) {
*first_submatch = matches[1].str();
}
return true;
}
/// Partially match a string against a regular expression.
/// \return true if a match was found.
inline bool app_regex_full_match(const std::string& perl_pattern, const std::string& str, std::string* first_submatch)
{
return app_regex_full_match(app_regex_re(perl_pattern), str, first_submatch);
}
/// Partially match a string against a regular expression.
/// \return true if a match was found.
inline bool app_regex_full_match(const char* perl_pattern, const std::string& str, std::string* first_submatch)
{
return app_regex_full_match(app_regex_re(perl_pattern), str, first_submatch);
}
/// Partially match a string against a regular expression.
/// \return true if a match was found.
inline bool app_regex_full_match(const std::regex& re, const std::string& str, std::vector<std::string*> matches_vector)
{
std::smatch matches;
if (!app_regex_full_match(re, str, matches) || (matches.size() + 1) < matches_vector.size()) {
return false;
}
for (std::size_t i = 1; i < matches_vector.size(); ++i) {
if (matches_vector[i - 1]) {
*(matches_vector[i - 1]) = matches.str(i);
}
}
return true;
}
/// Partially match a string against a regular expression.
/// \return true if a match was found.
inline bool app_regex_full_match(const std::string& perl_pattern, const std::string& str, std::vector<std::string*> matches_vector)
{
return app_regex_full_match(app_regex_re(perl_pattern), str, matches_vector);
}
/// Partially match a string against a regular expression.
/// \return true if a match was found.
inline bool app_regex_full_match(const char* perl_pattern, const std::string& str, std::vector<std::string*> matches_vector)
{
return app_regex_full_match(app_regex_re(perl_pattern), str, matches_vector);
}
/// Replace every occurrence of pattern with replacement string in \c subject.
/// \return number of replacements made.
inline int app_pcre_replace(const pcrecpp::RE& re, const std::string_view& replacement, std::string& subject);
inline void app_regex_replace(const std::regex& re, const std::string& replacement, std::string& subject)
{
subject = std::regex_replace(subject, re, replacement);
}
/// Replace every occurrence of pattern with replacement string in \c subject.
/// The pattern is in "/pattern/modifiers" format.
/// \return number of replacements made.
inline int app_pcre_replace(const std::string& perl_pattern, const std::string_view& replacement, std::string& subject);
inline void app_regex_replace(const std::string& perl_pattern, const std::string& replacement, std::string& subject)
{
app_regex_replace(app_regex_re(perl_pattern), replacement, subject);
}
/// Replace every occurrence of pattern with replacement string in \c subject.
/// The pattern is in "/pattern/modifiers" format.
/// \return number of replacements made.
inline int app_pcre_replace(const char* perl_pattern, const std::string_view& replacement, std::string& subject);
inline void app_regex_replace(const char* perl_pattern, const std::string& replacement, std::string& subject)
{
app_regex_replace(app_regex_re(perl_pattern), replacement, subject);
}
/// Replace first occurrence of pattern with replacement string in \c subject.
/// \return true if a replacement was made
inline bool app_pcre_replace_once(const pcrecpp::RE& re, const std::string_view& replacement, std::string& subject);
/// Replace the first occurrence of pattern with replacement string in \c subject.
/// The pattern is in "/pattern/modifiers" format.
/// \return true if a replacement was made
inline bool app_pcre_replace_once(const std::string& perl_pattern, const std::string_view& replacement, std::string& subject);
/// Replace the first occurrence of pattern with replacement string in \c subject.
/// The pattern is in "/pattern/modifiers" format.
/// \return true if a replacement was made
inline bool app_pcre_replace_once(const char* perl_pattern, const std::string_view& replacement, std::string& subject);
*/
/// Escape a string to be used inside a regular expression. The result
/// won't contain any special expression characters.
@@ -302,175 +347,29 @@ inline std::string app_regex_escape(const std::string& str)
{
// Based on
// https://stackoverflow.com/questions/39228912/stdregex-escape-special-characters-for-use-in-regex
static const std::regex metacharacters(R"([\.\^\$\-\+\(\)\[\]\{\}\|\?\*)");
return std::regex_replace(str, metacharacters, "\\$&");
static const std::map<std::string, std::string> replacements {
{"\\", "\\\\"},
{"^", "\\^"},
{"$", "\\$"},
// {"-", "\\-"},
{"|", "\\|"},
{".", "\\."},
{"?", "\\?"},
{"*", "\\*"},
{"+", "\\+"},
{"(", "\\("},
{")", "\\)"},
{"[", "\\["},
{"]", "\\]"},
{"{", "\\{"},
{"}", "\\}"},
};
return hz::string_replace_array_copy(str, replacements);
}
// ------------------------------------------- Implementation
/*
bool app_pcre_match(const pcrecpp::RE& re, const std::string_view& str,
const pcrecpp::Arg& matched_ptr1,
const pcrecpp::Arg& matched_ptr2,
const pcrecpp::Arg& matched_ptr3,
const pcrecpp::Arg& matched_ptr4,
const pcrecpp::Arg& matched_ptr5,
const pcrecpp::Arg& matched_ptr6,
const pcrecpp::Arg& matched_ptr7,
const pcrecpp::Arg& matched_ptr8,
const pcrecpp::Arg& matched_ptr9,
const pcrecpp::Arg& matched_ptr10,
const pcrecpp::Arg& matched_ptr11,
const pcrecpp::Arg& matched_ptr12,
const pcrecpp::Arg& matched_ptr13,
const pcrecpp::Arg& matched_ptr14,
const pcrecpp::Arg& matched_ptr15,
const pcrecpp::Arg& matched_ptr16)
{
return re.PartialMatch({str.data(), static_cast<int>(str.size())},
matched_ptr1,
matched_ptr2,
matched_ptr3,
matched_ptr4,
matched_ptr5,
matched_ptr6,
matched_ptr7,
matched_ptr8,
matched_ptr9,
matched_ptr10,
matched_ptr11,
matched_ptr12,
matched_ptr13,
matched_ptr14,
matched_ptr15,
matched_ptr16);
}
bool app_pcre_match(const std::string& perl_pattern, const std::string_view& str,
const pcrecpp::Arg& matched_ptr1,
const pcrecpp::Arg& matched_ptr2,
const pcrecpp::Arg& matched_ptr3,
const pcrecpp::Arg& matched_ptr4,
const pcrecpp::Arg& matched_ptr5,
const pcrecpp::Arg& matched_ptr6,
const pcrecpp::Arg& matched_ptr7,
const pcrecpp::Arg& matched_ptr8,
const pcrecpp::Arg& matched_ptr9,
const pcrecpp::Arg& matched_ptr10,
const pcrecpp::Arg& matched_ptr11,
const pcrecpp::Arg& matched_ptr12,
const pcrecpp::Arg& matched_ptr13,
const pcrecpp::Arg& matched_ptr14,
const pcrecpp::Arg& matched_ptr15,
const pcrecpp::Arg& matched_ptr16)
{
return app_pcre_match(app_pcre_re(perl_pattern), str,
matched_ptr1,
matched_ptr2,
matched_ptr3,
matched_ptr4,
matched_ptr5,
matched_ptr6,
matched_ptr7,
matched_ptr8,
matched_ptr9,
matched_ptr10,
matched_ptr11,
matched_ptr12,
matched_ptr13,
matched_ptr14,
matched_ptr15,
matched_ptr16);
}
bool app_pcre_match(const char* perl_pattern, const std::string_view& str,
const pcrecpp::Arg& matched_ptr1,
const pcrecpp::Arg& matched_ptr2,
const pcrecpp::Arg& matched_ptr3,
const pcrecpp::Arg& matched_ptr4,
const pcrecpp::Arg& matched_ptr5,
const pcrecpp::Arg& matched_ptr6,
const pcrecpp::Arg& matched_ptr7,
const pcrecpp::Arg& matched_ptr8,
const pcrecpp::Arg& matched_ptr9,
const pcrecpp::Arg& matched_ptr10,
const pcrecpp::Arg& matched_ptr11,
const pcrecpp::Arg& matched_ptr12,
const pcrecpp::Arg& matched_ptr13,
const pcrecpp::Arg& matched_ptr14,
const pcrecpp::Arg& matched_ptr15,
const pcrecpp::Arg& matched_ptr16)
{
return app_pcre_match(app_pcre_re(perl_pattern), str,
matched_ptr1,
matched_ptr2,
matched_ptr3,
matched_ptr4,
matched_ptr5,
matched_ptr6,
matched_ptr7,
matched_ptr8,
matched_ptr9,
matched_ptr10,
matched_ptr11,
matched_ptr12,
matched_ptr13,
matched_ptr14,
matched_ptr15,
matched_ptr16);
}
int app_pcre_replace(const pcrecpp::RE& re, const std::string_view& replacement, std::string& subject)
{
return re.GlobalReplace({replacement.data(), static_cast<int>(replacement.size())}, &subject);
}
int app_pcre_replace(const std::string& perl_pattern, const std::string_view& replacement, std::string& subject)
{
return app_pcre_replace(app_pcre_re(perl_pattern), replacement, subject);
}
int app_pcre_replace(const char* perl_pattern, const std::string_view& replacement, std::string& subject)
{
return app_pcre_replace(app_pcre_re(perl_pattern), replacement, subject);
}
bool app_pcre_replace_once(const pcrecpp::RE& re, const std::string_view& replacement, std::string& subject)
{
return re.Replace({replacement.data(), static_cast<int>(replacement.size())}, &subject);
}
bool app_pcre_replace_once(const std::string& perl_pattern, const std::string_view& replacement, std::string& subject)
{
return app_pcre_replace_once(app_pcre_re(perl_pattern), replacement, subject);
}
bool app_pcre_replace_once(const char* perl_pattern, const std::string_view& replacement, std::string& subject)
{
return app_pcre_replace_once(app_pcre_re(perl_pattern), replacement, subject);
}
*/
#endif
File diff suppressed because it is too large Load Diff
+21 -19
View File
@@ -25,13 +25,12 @@ Copyright:
#include "hz/string_num.h" // string_is_numeric, number_to_string
//#include "hz/debug.h" // debug_*
#include "app_pcrecpp.h"
#include "app_regex.h"
//#include "ata_storage_property_descr.h"
// #include "warning_colors.h"
#include "smartctl_parser_types.h"
#include "smartctl_version_parser.h"
#include "smartctl_text_parser_helper.h"
#include "storage_device.h"
@@ -76,33 +75,36 @@ hz::ExpectedVoid<SmartctlParserError> SmartctlTextBasicParser::parse(std::string
// Sample output line 2 (encountered on a BDRW drive):
// Device type: CD/DVD
// NOTE: CD/DVD detection does not work in "-d scsi" mode.
if (app_pcre_match("/this device: CD\\/DVD/mi", output)
|| app_pcre_match("/^Device type:\\s+CD\\/DVD/mi", output)) {
if (app_regex_partial_match("/this device: CD\\/DVD/mi", output)
|| app_regex_partial_match("/^Device type:\\s+CD\\/DVD/mi", output)) {
StorageProperty p;
p.set_name("Drive type", "_text_only/custom/parser_detected_drive_type", "Parser-Detected Drive Type");
p.reported_value = "CD/DVD";
p.value = StorageDeviceDetectedTypeExt::get_storable_name(StorageDeviceDetectedType::CdDvd);
p.readable_value = StorageDeviceDetectedTypeExt::get_displayable_name(StorageDeviceDetectedType::CdDvd);
p.section = StoragePropertySection::Info; // add to info section
add_property(p);
// This was encountered on a csmi soft-raid under windows with pd0.
// The device reported that it had smart supported and enabled.
// Product: Raid 5 Volume
} else if (app_pcre_match("/Product:[ \\t]*Raid/mi", output)) {
} else if (app_regex_partial_match("/Product:[ \\t]*Raid/mi", output)) {
StorageProperty p;
p.set_name("Drive type", "_text_only/custom/parser_detected_drive_type", "Parser-Detected Drive Type");
p.reported_value = "RAID";
p.value = StorageDeviceDetectedTypeExt::get_storable_name(StorageDeviceDetectedType::UnsupportedRaid);
p.readable_value = StorageDeviceDetectedTypeExt::get_displayable_name(StorageDeviceDetectedType::UnsupportedRaid);
p.section = StoragePropertySection::Info; // add to info section
add_property(p);
is_raid = true;
} else if (app_pcre_match("/ATA Version is:/mi", output)) {
} else if (app_regex_partial_match("/ATA Version is:/mi", output)) {
StorageProperty p;
p.set_name("Drive type", "_text_only/custom/parser_detected_drive_type", "Parser-Detected Drive Type");
p.reported_value = "(S)ATA";
p.value = StorageDeviceDetectedTypeExt::get_storable_name(StorageDeviceDetectedType::AtaAny);
p.readable_value = StorageDeviceDetectedTypeExt::get_displayable_name(StorageDeviceDetectedType::AtaAny);
p.section = StoragePropertySection::Info; // add to info section
add_property(p);
}
@@ -122,19 +124,19 @@ hz::ExpectedVoid<SmartctlParserError> SmartctlTextBasicParser::parse(std::string
// Compared to SmartctlTextAtaParser, this one is much looser.
// Don't put complete messages here - they change across smartctl versions.
if (app_pcre_match("/^SMART support is:[ \\t]*Unavailable/mi", output) // cdroms output this
|| app_pcre_match("/Device does not support SMART/mi", output) // usb flash drives, non-smart hds
|| app_pcre_match("/Device Read Identity Failed/mi", output)) { // solaris scsi, unsupported by smartctl (maybe others?)
if (app_regex_partial_match("/^SMART support is:[ \\t]*Unavailable/mi", output) // cdroms output this
|| app_regex_partial_match("/Device does not support SMART/mi", output) // usb flash drives, non-smart hds
|| app_regex_partial_match("/Device Read Identity Failed/mi", output)) { // solaris scsi, unsupported by smartctl (maybe others?)
smart_supported = false;
smart_enabled = false;
} else if (app_pcre_match("/^SMART support is:[ \\t]*Available/mi", output)
|| app_pcre_match("/^SMART support is:[ \\t]*Ambiguous/mi", output)) {
} else if (app_regex_partial_match("/^SMART support is:[ \\t]*Available/mi", output)
|| app_regex_partial_match("/^SMART support is:[ \\t]*Ambiguous/mi", output)) {
smart_supported = true;
if (app_pcre_match("/^SMART support is:[ \\t]*Enabled/mi", output)) {
if (app_regex_partial_match("/^SMART support is:[ \\t]*Enabled/mi", output)) {
smart_enabled = true;
} else if (app_pcre_match("/^SMART support is:[ \\t]*Disabled/mi", output)) {
} else if (app_regex_partial_match("/^SMART support is:[ \\t]*Disabled/mi", output)) {
smart_enabled = false;
}
}
@@ -157,14 +159,14 @@ hz::ExpectedVoid<SmartctlParserError> SmartctlTextBasicParser::parse(std::string
std::string model;
if (app_pcre_match("/^Device Model:[ \\t]*(.*)$/mi", output, &model)) { // HDDs and CDROMs
if (app_regex_partial_match("/^Device Model:[ \\t]*(.*)$/mi", output, &model)) { // HDDs and CDROMs
model = hz::string_remove_adjacent_duplicates_copy(hz::string_trim_copy(model), ' ');
StorageProperty p;
p.set_name("Device Model", "model_name", "Device Model");
p.value = model; // string-type value
add_property(p);
} else if (app_pcre_match("/^(?:Device|Product):[ \\t]*(.*)$/mi", output, &model)) { // usb flash drives
} else if (app_regex_partial_match("/^(?:Device|Product):[ \\t]*(.*)$/mi", output, &model)) { // usb flash drives
model = hz::string_remove_adjacent_duplicates_copy(hz::string_trim_copy(model), ' ');
StorageProperty p;
p.set_name("Device Model", "model_name", "Device Model");
@@ -174,7 +176,7 @@ hz::ExpectedVoid<SmartctlParserError> SmartctlTextBasicParser::parse(std::string
std::string family; // this is from smartctl's database
if (app_pcre_match("/^Model Family:[ \\t]*(.*)$/mi", output, &family)) {
if (app_regex_partial_match("/^Model Family:[ \\t]*(.*)$/mi", output, &family)) {
family = hz::string_remove_adjacent_duplicates_copy(hz::string_trim_copy(family), ' ');
StorageProperty p;
p.set_name("Model Family", "model_family", "Model Family");
@@ -183,7 +185,7 @@ hz::ExpectedVoid<SmartctlParserError> SmartctlTextBasicParser::parse(std::string
}
std::string serial;
if (app_pcre_match("/^Serial Number:[ \\t]*(.*)$/mi", output, &serial)) {
if (app_regex_partial_match("/^Serial Number:[ \\t]*(.*)$/mi", output, &serial)) {
serial = hz::string_remove_adjacent_duplicates_copy(hz::string_trim_copy(serial), ' ');
StorageProperty p;
p.set_name("Serial Number", "serial_number", "Serial Number");
@@ -192,7 +194,7 @@ hz::ExpectedVoid<SmartctlParserError> SmartctlTextBasicParser::parse(std::string
}
std::string rpm_str;
if (app_pcre_match("/^Rotation Rate:[ \\t]*(.*)$/mi", output, &rpm_str)) {
if (app_regex_partial_match("/^Rotation Rate:[ \\t]*(.*)$/mi", output, &rpm_str)) {
StorageProperty p;
p.set_name("Rotation Rate", "rotation_rate", "Rotation Rate");
p.reported_value = rpm_str;
@@ -204,7 +206,7 @@ hz::ExpectedVoid<SmartctlParserError> SmartctlTextBasicParser::parse(std::string
// Note: this property is present since 5.33.
std::string size;
if (app_pcre_match("/^User Capacity:[ \\t]*(.*)$/mi", output, &size)) {
if (app_regex_partial_match("/^User Capacity:[ \\t]*(.*)$/mi", output, &size)) {
int64_t bytes = 0;
const std::string readable_size = SmartctlTextParserHelper::parse_byte_size(size, bytes, false);
StorageProperty p;
+1 -1
View File
@@ -30,7 +30,7 @@ bool SmartctlVersionParser::parse_version_text(const std::string& s, std::string
// "smartctl 5.39 2009-08-08 r2873" (svn versions)
// "smartctl 7.3 (build date Feb 11 2022)" (git versions)
// "smartctl pre-7.4 2023-06-13 r5481" (pre-releases)
if (!app_regex_partial_match(R"(/^smartctl (?:version )?(?:pre-)?(([0-9][^ \t\n\r]+)(?: [0-9 r:-]+)?)/mi)", s, {&version_full, &version_full})) {
if (!app_regex_partial_match(R"(/^smartctl (?:version )?(?:pre-)?(([0-9][^ \t\n\r]+)(?: [0-9 r:-]+)?)/mi)", s, {&version_only, &version_full})) {
debug_out_error("app", DBG_FUNC_MSG << "No smartctl version information found in supplied string.\n");
return false;
}