From 093515c3ec0aac977a861e4b149026e042beb5a2 Mon Sep 17 00:00:00 2001 From: Eric Mertens Date: Sat, 25 Jan 2025 15:45:31 -0800 Subject: [PATCH] mass reformat --- .clang-format | 232 ++++++++++++++++++++++++++++++++++++++++ connection.cpp | 92 +++++++++------- connection.hpp | 22 ++-- irc_coroutine.cpp | 17 ++- irc_coroutine.hpp | 88 +++++++++------ ircmsg.cpp | 137 +++++++++++++++--------- ircmsg.hpp | 44 +++++--- linebuffer.hpp | 8 +- main.cpp | 25 +++-- registration_thread.cpp | 65 ++++++----- registration_thread.hpp | 12 +-- sasl_mechanism.hpp | 4 - self_thread.cpp | 92 ++++++++++------ self_thread.hpp | 34 +++--- settings.cpp | 8 +- settings.hpp | 5 +- snote.cpp | 85 +++++++-------- 17 files changed, 659 insertions(+), 311 deletions(-) create mode 100644 .clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..7cb69d2 --- /dev/null +++ b/.clang-format @@ -0,0 +1,232 @@ +--- +Language: Cpp +# BasedOnStyle: WebKit +AccessModifierOffset: -4 +AlignAfterOpenBracket: BlockIndent +AlignArrayOfStructures: None +AlignConsecutiveAssignments: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionPointers: false + PadOperators: true +AlignConsecutiveBitFields: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionPointers: false + PadOperators: false +AlignConsecutiveDeclarations: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionPointers: false + PadOperators: false +AlignConsecutiveMacros: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionPointers: false + PadOperators: false +AlignConsecutiveShortCaseStatements: + Enabled: false + AcrossEmptyLines: false + AcrossComments: false + AlignCaseColons: false +AlignEscapedNewlines: Right +AlignOperands: DontAlign +AlignTrailingComments: + Kind: Never + OverEmptyLines: 0 +AllowAllArgumentsOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowBreakBeforeNoexceptSpecifier: Never +AllowShortBlocksOnASingleLine: Empty +AllowShortCaseLabelsOnASingleLine: false +AllowShortCompoundRequirementOnASingleLine: true +AllowShortEnumsOnASingleLine: true +AllowShortFunctionsOnASingleLine: All +AllowShortIfStatementsOnASingleLine: Never +AllowShortLambdasOnASingleLine: All +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: MultiLine +AttributeMacros: + - __capability +BinPackArguments: true +BinPackParameters: true +BitFieldColonSpacing: Both +BraceWrapping: + AfterCaseLabel: false + AfterClass: true + AfterControlStatement: Always + AfterEnum: true + AfterExternBlock: false + AfterFunction: true + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: true + AfterUnion: true + BeforeCatch: true + BeforeElse: true + BeforeLambdaBody: false + BeforeWhile: true + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakAdjacentStringLiterals: true +BreakAfterAttributes: Leave +BreakAfterJavaFieldAnnotations: false +BreakArrays: true +BreakBeforeBinaryOperators: All +BreakBeforeConceptDeclarations: Always +BreakBeforeBraces: Custom +BreakBeforeInlineASMColon: OnlyMultiline +BreakBeforeTernaryOperators: true +BreakConstructorInitializers: BeforeComma +BreakInheritanceList: BeforeColon +BreakStringLiterals: true +ColumnLimit: 0 +CommentPragmas: "^ IWYU pragma:" +CompactNamespaces: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +DisableFormat: false +EmptyLineAfterAccessModifier: Never +EmptyLineBeforeAccessModifier: LogicalBlock +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: false +ForEachMacros: [] +IfMacros: [] +IncludeBlocks: Preserve +IncludeCategories: + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 2 + SortPriority: 0 + CaseSensitive: false + - Regex: '^(<|"(gtest|gmock|isl|json)/)' + Priority: 3 + SortPriority: 0 + CaseSensitive: false + - Regex: ".*" + Priority: 1 + SortPriority: 0 + CaseSensitive: false +IncludeIsMainRegex: "(Test)?$" +IncludeIsMainSourceRegex: "" +IndentAccessModifiers: false +IndentCaseBlocks: false +IndentCaseLabels: false +IndentExternBlock: AfterExternBlock +IndentGotoLabels: true +IndentPPDirectives: None +IndentRequiresClause: true +IndentWidth: 4 +IndentWrappedFunctionNames: false +InsertBraces: false +InsertNewlineAtEOF: false +InsertTrailingCommas: None +IntegerLiteralSeparator: + Binary: 0 + BinaryMinDigits: 0 + Decimal: 0 + DecimalMinDigits: 0 + Hex: 0 + HexMinDigits: 0 +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: true +KeepEmptyLinesAtEOF: false +LambdaBodyIndentation: Signature +LineEnding: LF +MacroBlockBegin: "" +MacroBlockEnd: "" +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: Inner +ObjCBinPackProtocolList: Auto +ObjCBlockIndentWidth: 4 +ObjCBreakBeforeNestedBlockParam: true +ObjCSpaceAfterProperty: true +ObjCSpaceBeforeProtocolList: true +PackConstructorInitializers: BinPack +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakOpenParenthesis: 0 +PenaltyBreakScopeResolution: 500 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyIndentedWhitespace: 0 +PenaltyReturnTypeOnItsOwnLine: 60 +PointerAlignment: Right +PPIndentWidth: -1 +QualifierAlignment: Left +ReferenceAlignment: Pointer +ReflowComments: true +RemoveBracesLLVM: false +RemoveParentheses: Leave +RemoveSemicolon: false +RequiresClausePosition: OwnLine +RequiresExpressionIndentation: OuterScope +SeparateDefinitionBlocks: Leave +ShortNamespaceLines: 1 +SkipMacroDefinitionBody: false +SortIncludes: CaseSensitive +SortJavaStaticImport: Before +SortUsingDeclarations: LexicographicNumeric +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceAroundPointerQualifiers: Default +SpaceBeforeAssignmentOperators: true +SpaceBeforeCaseColon: false +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeJsonColon: false +SpaceBeforeParens: ControlStatements +SpaceBeforeParensOptions: + AfterControlStatements: true + AfterForeachMacros: true + AfterFunctionDefinitionName: false + AfterFunctionDeclarationName: false + AfterIfMacros: true + AfterOverloadedOperator: false + AfterPlacementOperator: true + AfterRequiresInClause: false + AfterRequiresInExpression: false + BeforeNonEmptyParentheses: false +SpaceBeforeRangeBasedForLoopColon: true +SpaceBeforeSquareBrackets: false +SpaceInEmptyBlock: true +SpacesBeforeTrailingComments: 1 +SpacesInAngles: Never +SpacesInContainerLiterals: true +SpacesInLineCommentPrefix: + Minimum: 1 + Maximum: -1 +SpacesInParens: Never +SpacesInParensOptions: + InCStyleCasts: false + InConditionalStatements: false + InEmptyParentheses: false + Other: false +SpacesInSquareBrackets: false +Standard: Latest +StatementAttributeLikeMacros: [] +StatementMacros: [] +TabWidth: 8 +UseTab: Never +VerilogBreakBetweenInstancePorts: true +WhitespaceSensitiveMacros: [] diff --git a/connection.cpp b/connection.cpp index e81f770..a227094 100644 --- a/connection.cpp +++ b/connection.cpp @@ -12,11 +12,11 @@ namespace { using namespace std::literals; -Connection::Connection(boost::asio::io_context & io) -: stream_{io} -, watchdog_timer_{io} -, write_posted_{false} -, stalled_{false} +Connection::Connection(boost::asio::io_context &io) + : stream_{io} + , watchdog_timer_{io} + , write_posted_{false} + , stalled_{false} { } @@ -24,28 +24,32 @@ auto Connection::write_buffers() -> void { std::vector buffers; buffers.reserve(write_strings_.size()); - for (auto const& elt : write_strings_) + for (const auto &elt : write_strings_) { buffers.push_back(boost::asio::buffer(elt)); } boost::asio::async_write( stream_, buffers, - [this, strings = std::move(write_strings_)](boost::system::error_code const& error, std::size_t) - { - if (not error) { - if (write_strings_.empty()) { + [this, strings = std::move(write_strings_)](const boost::system::error_code &error, std::size_t) { + if (not error) + { + if (write_strings_.empty()) + { write_posted_ = false; - } else { + } + else + { write_buffers(); } } - }); + } + ); write_strings_.clear(); } auto Connection::connect( - boost::asio::io_context & io, + boost::asio::io_context &io, std::string host, std::string port ) -> boost::asio::awaitable @@ -53,29 +57,28 @@ auto Connection::connect( using namespace std::placeholders; // keep connection alive while coroutine is active - auto const self = shared_from_this(); + const auto self = shared_from_this(); { auto resolver = boost::asio::ip::tcp::resolver{io}; - auto const endpoints = co_await resolver.async_resolve(host, port, boost::asio::use_awaitable); - auto const endpoint = co_await boost::asio::async_connect(stream_, endpoints, boost::asio::use_awaitable); - BOOST_LOG_TRIVIAL(debug) << "CONNECTED: " << endpoint; + const auto endpoints = co_await resolver.async_resolve(host, port, boost::asio::use_awaitable); + const auto endpoint = co_await boost::asio::async_connect(stream_, endpoints, boost::asio::use_awaitable); + BOOST_LOG_TRIVIAL(debug) << "CONNECTED: " << endpoint; sig_connect(); } - // Start the queue writer after connection watchdog(); - for(LineBuffer buffer{32'768};;) + for (LineBuffer buffer{32'768};;) { boost::system::error_code error; - auto const n = co_await stream_.async_read_some(buffer.get_buffer(), boost::asio::redirect_error(boost::asio::use_awaitable, error)); + const auto n = co_await stream_.async_read_some(buffer.get_buffer(), boost::asio::redirect_error(boost::asio::use_awaitable, error)); if (error) { break; } - buffer.add_bytes(n, [this](char * line) { + buffer.add_bytes(n, [this](char *line) { BOOST_LOG_TRIVIAL(debug) << "RECV: " << line; watchdog_activity(); dispatch_line(line); @@ -84,14 +87,15 @@ auto Connection::connect( watchdog_timer_.cancel(); stream_.close(); + + BOOST_LOG_TRIVIAL(debug) << "DISCONNECTED"; sig_disconnect(); } auto Connection::watchdog() -> void { watchdog_timer_.expires_after(watchdog_duration); - watchdog_timer_.async_wait([this](auto const& error) - { + watchdog_timer_.async_wait([this](const auto &error) { if (not error) { if (stalled_) @@ -118,15 +122,17 @@ auto Connection::watchdog_activity() -> void /// Parse IRC message line and dispatch it to the ircmsg slot. auto Connection::dispatch_line(char *line) -> void { - auto const msg = parse_irc_message(line); - auto const recognized = IrcCommandHash::in_word_set(msg.command.data(), msg.command.size()); - auto const command + const auto msg = parse_irc_message(line); + const auto recognized = IrcCommandHash::in_word_set(msg.command.data(), msg.command.size()); + const auto command = recognized - && recognized->min_args <= msg.args.size() - && recognized->max_args >= msg.args.size() - ? recognized->command : IrcCommand::UNKNOWN; + && recognized->min_args <= msg.args.size() + && recognized->max_args >= msg.args.size() + ? recognized->command + : IrcCommand::UNKNOWN; - switch (command) { + switch (command) + { // Respond to pings immediate and discard case IrcCommand::PING: @@ -145,7 +151,8 @@ auto Connection::dispatch_line(char *line) -> void // Server notice generate snote events but not IRC command events case IrcCommand::NOTICE: - if (auto match = snoteCore.match(msg)) { + if (auto match = snoteCore.match(msg)) + { sig_snote(*match); break; } @@ -156,7 +163,6 @@ auto Connection::dispatch_line(char *line) -> void sig_ircmsg(command, msg); break; } - } auto Connection::write_line(std::string message) -> void @@ -165,9 +171,10 @@ auto Connection::write_line(std::string message) -> void message += "\r\n"; write_strings_.push_back(std::move(message)); - if (not write_posted_) { + if (not write_posted_) + { write_posted_ = true; - boost::asio::post(stream_.get_executor(), [weak = weak_from_this()](){ + boost::asio::post(stream_.get_executor(), [weak = weak_from_this()]() { if (auto self = weak.lock()) { self->write_buffers(); @@ -181,8 +188,7 @@ auto Connection::close() -> void stream_.close(); } -static -auto is_invalid_last(char x) -> bool +static auto is_invalid_last(char x) -> bool { return x == '\0' || x == '\r' || x == '\n'; } @@ -261,7 +267,8 @@ auto Connection::send_authenticate(std::string_view message) -> void auto Connection::on_authenticate(const std::string_view chunk) -> void { - if (chunk != "+"sv) { + if (chunk != "+"sv) + { authenticate_buffer_ += chunk; } @@ -275,7 +282,9 @@ auto Connection::on_authenticate(const std::string_view chunk) -> void { decoded.resize(len); sig_authenticate(decoded); - } else { + } + else + { BOOST_LOG_TRIVIAL(debug) << "Invalid AUTHENTICATE base64"sv; send_authenticate("*"sv); // abort SASL } @@ -300,9 +309,10 @@ auto Connection::send_authenticate_encoded(std::string_view body) -> void std::string encoded(mybase64::encoded_size(body.size()), 0); mybase64::encode(body, encoded.data()); - for (size_t lo = 0; lo < encoded.size(); lo += 400) { + for (size_t lo = 0; lo < encoded.size(); lo += 400) + { const auto hi = std::min(lo + 400, encoded.size()); - const std::string_view chunk { encoded.begin() + lo, encoded.begin() + hi }; + const std::string_view chunk{encoded.begin() + lo, encoded.begin() + hi}; send_authenticate(chunk); } @@ -310,4 +320,4 @@ auto Connection::send_authenticate_encoded(std::string_view body) -> void { send_authenticate("+"sv); } -} \ No newline at end of file +} diff --git a/connection.hpp b/connection.hpp index e78a32f..849d69b 100644 --- a/connection.hpp +++ b/connection.hpp @@ -1,7 +1,7 @@ #pragma once -#include "ircmsg.hpp" #include "irc_command.hpp" +#include "ircmsg.hpp" #include "snote.hpp" #include @@ -27,7 +27,7 @@ private: std::string authenticate_buffer_; auto write_buffers() -> void; - auto dispatch_line(char * line) -> void; + auto dispatch_line(char *line) -> void; static constexpr std::chrono::seconds watchdog_duration = std::chrono::seconds{30}; auto watchdog() -> void; @@ -40,10 +40,10 @@ private: auto write_irc(std::string) -> void; auto write_irc(std::string, std::string_view) -> void; template - auto write_irc(std::string front, std::string_view next, Args ...rest) -> void; + auto write_irc(std::string front, std::string_view next, Args... rest) -> void; public: - Connection(boost::asio::io_context & io); + Connection(boost::asio::io_context &io); boost::signals2::signal sig_connect; boost::signals2::signal sig_disconnect; @@ -51,12 +51,13 @@ public: boost::signals2::signal sig_snote; boost::signals2::signal sig_authenticate; - auto get_executor() -> boost::asio::any_io_executor { + auto get_executor() -> boost::asio::any_io_executor + { return stream_.get_executor(); } auto connect( - boost::asio::io_context & io, + boost::asio::io_context &io, std::string host, std::string port ) -> boost::asio::awaitable; @@ -81,16 +82,15 @@ public: }; template -auto Connection::write_irc(std::string front, std::string_view next, Args ...rest) -> void +auto Connection::write_irc(std::string front, std::string_view next, Args... rest) -> void { - auto const is_invalid = [](char const x) -> bool - { + const auto is_invalid = [](const char x) -> bool { return x == '\0' || x == '\r' || x == '\n' || x == ' '; }; if (next.empty() - || next.front() == ':' - || next.end() != std::find_if(next.begin(), next.end(), is_invalid)) + || next.front() == ':' + || next.end() != std::find_if(next.begin(), next.end(), is_invalid)) { throw std::runtime_error{"bad irc argument"}; } diff --git a/irc_coroutine.cpp b/irc_coroutine.cpp index 9269dca..f2308c9 100644 --- a/irc_coroutine.cpp +++ b/irc_coroutine.cpp @@ -1,21 +1,20 @@ #include "irc_coroutine.hpp" -auto irc_coroutine::is_running() -> bool { +auto irc_coroutine::is_running() -> bool +{ return promise().connection_ != nullptr; } -auto irc_coroutine::exception() -> std::exception_ptr { +auto irc_coroutine::exception() -> std::exception_ptr +{ return promise().exception_; } -auto irc_coroutine::start(Connection& connection) -> void { +auto irc_coroutine::start(Connection &connection) -> void +{ promise().connection_ = connection.shared_from_this(); resume(); } -void wait_ircmsg::stop() { - ircmsg_slot_.disconnect(); -} +void wait_ircmsg::stop() { ircmsg_slot_.disconnect(); } -void wait_timeout::stop() { - timer_.reset(); -} +void wait_timeout::stop() { timer_.reset(); } diff --git a/irc_coroutine.hpp b/irc_coroutine.hpp index 4866326..f5fd617 100644 --- a/irc_coroutine.hpp +++ b/irc_coroutine.hpp @@ -11,7 +11,8 @@ struct irc_promise; /// A coroutine that can co_await on various IRC events -struct irc_coroutine : std::coroutine_handle { +struct irc_coroutine : std::coroutine_handle +{ using promise_type = irc_promise; /// Start the coroutine and associate it with a specific connection. @@ -44,22 +45,25 @@ struct irc_promise auto final_suspend() noexcept -> std::suspend_always { return {}; } // Normal termination - auto return_void() -> void { + auto return_void() -> void + { connection_.reset(); } // Abnormal termination - remember the exception - auto unhandled_exception() -> void { + auto unhandled_exception() -> void + { connection_.reset(); exception_ = std::current_exception(); } }; -template +template class Wait; /// Argument to a Wait that expects one or more IRC messages -class wait_ircmsg { +class wait_ircmsg +{ // Vector of commands this wait is expecting. Leave empty to accept all messages. std::vector want_cmds_; @@ -69,26 +73,38 @@ class wait_ircmsg { public: using result_type = std::pair; - wait_ircmsg(std::initializer_list want_cmds) : want_cmds_{want_cmds} {} + wait_ircmsg(std::initializer_list want_cmds) + : want_cmds_{want_cmds} + { + } - template auto start(Wait& command) -> void; + template + auto start(Wait &command) -> void; auto stop() -> void; }; -class wait_timeout { +class wait_timeout +{ std::optional timer_; std::chrono::milliseconds timeout_; public: - struct result_type {}; - wait_timeout(std::chrono::milliseconds timeout) : timeout_{timeout} {} + struct result_type + { + }; + wait_timeout(std::chrono::milliseconds timeout) + : timeout_{timeout} + { + } - template auto start(Wait& command) -> void; + template + auto start(Wait &command) -> void; auto stop() -> void; }; -template -class Wait { +template +class Wait +{ // State associated with each wait mode std::tuple modes_; @@ -105,31 +121,39 @@ class Wait { boost::signals2::scoped_connection disconnect_slot_; template - auto start_mode() -> void { + auto start_mode() -> void + { std::get(modes_).template start(*this); } template - auto start_modes(std::index_sequence) -> void { + auto start_modes(std::index_sequence) -> void + { (start_mode(), ...); } template - auto stop_modes(std::index_sequence) -> void { + auto stop_modes(std::index_sequence) -> void + { (std::get(modes_).stop(), ...); } public: - Wait(Ts &&...modes) : modes_{std::forward(modes)...} {} + Wait(Ts &&...modes) + : modes_{std::forward(modes)...} + { + } // Get the connection that this coroutine was started with. - auto get_connection() const -> Connection & { + auto get_connection() const -> Connection & + { return *handle_.promise().connection_; } // Store a successful result and resume the coroutine template - auto complete(Args &&...args) -> void { + auto complete(Args &&...args) -> void + { result_.emplace(std::in_place_index, std::forward(args)...); handle_.resume(); } @@ -148,23 +172,22 @@ template auto wait_ircmsg::start(Wait &command) -> void { ircmsg_slot_ = command.get_connection().sig_ircmsg.connect([this, &command](auto cmd, auto &msg) { - auto const wanted = - want_cmds_.empty() || - std::find(want_cmds_.begin(), want_cmds_.end(), cmd) != want_cmds_.end(); - if (wanted) { + const auto wanted = want_cmds_.empty() || std::find(want_cmds_.begin(), want_cmds_.end(), cmd) != want_cmds_.end(); + if (wanted) + { command.template complete(cmd, msg); } }); } template -auto wait_timeout::start(Wait& command) -> void +auto wait_timeout::start(Wait &command) -> void { timer_.emplace(command.get_connection().get_executor()); timer_->expires_after(timeout_); - timer_->async_wait([this, &command](auto const& error) - { - if (not error) { + timer_->async_wait([this, &command](const auto &error) { + if (not error) + { timer_.reset(); command.template complete(); } @@ -176,7 +199,7 @@ auto Wait::await_suspend(std::coroutine_handle handle) -> vo { handle_ = handle; - auto const tuple_size = std::tuple_size_v; + const auto tuple_size = std::tuple_size_v; start_modes(std::make_index_sequence{}); disconnect_slot_ = get_connection().sig_disconnect.connect([this]() { @@ -187,14 +210,17 @@ auto Wait::await_suspend(std::coroutine_handle handle) -> vo template auto Wait::await_resume() -> std::variant { - auto const tuple_size = std::tuple_size_v; + const auto tuple_size = std::tuple_size_v; stop_modes(std::make_index_sequence{}); disconnect_slot_.disconnect(); - if (result_) { + if (result_) + { return std::move(*result_); - } else { + } + else + { throw std::runtime_error{"connection terminated"}; } } diff --git a/ircmsg.cpp b/ircmsg.cpp index 0b819d6..1c21f4d 100644 --- a/ircmsg.cpp +++ b/ircmsg.cpp @@ -4,56 +4,68 @@ #include "ircmsg.hpp" namespace { -class Parser { - char* msg_; +class Parser +{ + char *msg_; inline static char empty[1]; - inline void trim() { - while (*msg_ == ' ') msg_++; + inline void trim() + { + while (*msg_ == ' ') + msg_++; } public: - Parser(char* msg) : msg_(msg) { - if (msg_ == nullptr) { + Parser(char *msg) + : msg_(msg) + { + if (msg_ == nullptr) + { msg_ = empty; - } else { + } + else + { trim(); } } - char* word() { - auto const start = msg_; - while (*msg_ != '\0' && *msg_ != ' ') msg_++; - if (*msg_ != '\0') { // prepare for next token + char *word() + { + const auto start = msg_; + while (*msg_ != '\0' && *msg_ != ' ') + msg_++; + if (*msg_ != '\0') + { // prepare for next token *msg_++ = '\0'; trim(); } return start; } - bool match(char c) { - if (c == *msg_) { + bool match(char c) + { + if (c == *msg_) + { msg_++; return true; } return false; } - bool isempty() const { - return *msg_ == '\0'; - } + bool isempty() const { return *msg_ == '\0'; } - char const* peek() { - return msg_; - } + const char *peek() { return msg_; } }; -std::string_view unescape_tag_value(char* const val) +std::string_view unescape_tag_value(char *const val) { // only start copying at the first escape character // skip everything before that auto cursor = strchr(val, '\\'); - if (cursor == nullptr) { return {val}; } + if (cursor == nullptr) + { + return {val}; + } auto write = cursor; for (; *cursor; cursor++) @@ -63,12 +75,23 @@ std::string_view unescape_tag_value(char* const val) cursor++; switch (*cursor) { - default : *write++ = *cursor; break; - case ':' : *write++ = ';' ; break; - case 's' : *write++ = ' ' ; break; - case 'r' : *write++ = '\r' ; break; - case 'n' : *write++ = '\n' ; break; - case '\0': return {val, write}; + default: + *write++ = *cursor; + break; + case ':': + *write++ = ';'; + break; + case 's': + *write++ = ' '; + break; + case 'r': + *write++ = '\r'; + break; + case 'n': + *write++ = '\n'; + break; + case '\0': + return {val, write}; } } else @@ -81,50 +104,61 @@ std::string_view unescape_tag_value(char* const val) } // namespace -auto parse_irc_tags(char* str) -> std::vector +auto parse_irc_tags(char *str) -> std::vector { std::vector tags; - do { + do + { auto val = strsep(&str, ";"); auto key = strsep(&val, "="); - if ('\0' == *key) { + if ('\0' == *key) + { throw irc_parse_error(irc_error_code::MISSING_TAG); } - if (nullptr == val) { + if (nullptr == val) + { tags.emplace_back(key, ""); - } else { - tags.emplace_back(std::string_view{key, val-1}, unescape_tag_value(val)); } - } while(nullptr != str); + else + { + tags.emplace_back(std::string_view{key, val - 1}, unescape_tag_value(val)); + } + } + while (nullptr != str); return tags; } -auto parse_irc_message(char* msg) -> IrcMsg +auto parse_irc_message(char *msg) -> IrcMsg { - Parser p {msg}; + Parser p{msg}; IrcMsg out; /* MESSAGE TAGS */ - if (p.match('@')) { + if (p.match('@')) + { out.tags = parse_irc_tags(p.word()); } /* MESSAGE SOURCE */ - if (p.match(':')) { + if (p.match(':')) + { out.source = p.word(); } /* MESSAGE COMMANDS */ out.command = p.word(); - if (out.command.empty()) { + if (out.command.empty()) + { throw irc_parse_error{irc_error_code::MISSING_COMMAND}; } /* MESSAGE ARGUMENTS */ - while (!p.isempty()) { - if (p.match(':')) { + while (!p.isempty()) + { + if (p.match(':')) + { out.args.push_back(p.peek()); break; } @@ -134,16 +168,19 @@ auto parse_irc_message(char* msg) -> IrcMsg return out; } -auto IrcMsg::hassource() const -> bool -{ - return source.data() != nullptr; -} +auto IrcMsg::hassource() const -> bool { return source.data() != nullptr; } -auto operator<<(std::ostream& out, irc_error_code code) -> std::ostream& +auto operator<<(std::ostream &out, irc_error_code code) -> std::ostream & { - switch(code) { - case irc_error_code::MISSING_COMMAND: out << "MISSING COMMAND"; return out; - case irc_error_code::MISSING_TAG: out << "MISSING TAG"; return out; - default: return out; + switch (code) + { + case irc_error_code::MISSING_COMMAND: + out << "MISSING COMMAND"; + return out; + case irc_error_code::MISSING_TAG: + out << "MISSING TAG"; + return out; + default: + return out; } } diff --git a/ircmsg.hpp b/ircmsg.hpp index 15c1904..28a9542 100644 --- a/ircmsg.hpp +++ b/ircmsg.hpp @@ -9,9 +9,13 @@ struct irctag std::string_view key; std::string_view val; - irctag(std::string_view key, std::string_view val) : key{key}, val{val} {} + irctag(std::string_view key, std::string_view val) + : key{key} + , val{val} + { + } - friend auto operator==(irctag const&, irctag const&) -> bool = default; + friend auto operator==(const irctag &, const irctag &) -> bool = default; }; struct IrcMsg @@ -24,30 +28,38 @@ struct IrcMsg IrcMsg() = default; IrcMsg( - std::vector && tags, + std::vector &&tags, std::string_view source, std::string_view command, - std::vector && args) - : tags(std::move(tags)), - args(std::move(args)), - source{source}, - command{command} {} + std::vector &&args + ) + : tags(std::move(tags)) + , args(std::move(args)) + , source{source} + , command{command} + { + } - bool hassource() const; + bool hassource() const; - friend bool operator==(IrcMsg const&, IrcMsg const&) = default; + friend bool operator==(const IrcMsg &, const IrcMsg &) = default; }; -enum class irc_error_code { +enum class irc_error_code +{ MISSING_TAG, MISSING_COMMAND, }; -auto operator<<(std::ostream& out, irc_error_code) -> std::ostream&; +auto operator<<(std::ostream &out, irc_error_code) -> std::ostream &; -struct irc_parse_error : public std::exception { +struct irc_parse_error : public std::exception +{ irc_error_code code; - irc_parse_error(irc_error_code code) : code(code) {} + irc_parse_error(irc_error_code code) + : code(code) + { + } }; /** @@ -57,6 +69,6 @@ struct irc_parse_error : public std::exception { * * Returns zero for success, non-zero for parse error. */ -auto parse_irc_message(char* msg) -> IrcMsg; +auto parse_irc_message(char *msg) -> IrcMsg; -auto parse_irc_tags(char* msg) -> std::vector; +auto parse_irc_tags(char *msg) -> std::vector; diff --git a/linebuffer.hpp b/linebuffer.hpp index a832ec0..531f453 100644 --- a/linebuffer.hpp +++ b/linebuffer.hpp @@ -34,7 +34,11 @@ public: * * @param n Buffer size */ - LineBuffer(std::size_t n) : buffer(n), end_{buffer.begin()} {} + LineBuffer(std::size_t n) + : buffer(n) + , end_{buffer.begin()} + { + } /** * @brief Get the available buffer space @@ -60,7 +64,7 @@ public: */ auto add_bytes(std::size_t n, std::invocable auto line_cb) -> void { - auto const start = end_; + const auto start = end_; std::advance(end_, n); // new data is now located in [start, end_) diff --git a/main.cpp b/main.cpp index b5159ee..c27c44c 100644 --- a/main.cpp +++ b/main.cpp @@ -13,11 +13,11 @@ using namespace std::chrono_literals; -auto start(boost::asio::io_context & io, Settings const& settings) -> void +auto start(boost::asio::io_context &io, const Settings &settings) -> void { - auto const connection = std::make_shared(io); + const auto connection = std::make_shared(io); - auto const selfThread = SelfThread::start(*connection); + const auto selfThread = SelfThread::start(*connection); RegistrationThread::start(*connection, settings, selfThread); connection->sig_snote.connect([](auto &match) { @@ -29,22 +29,21 @@ auto start(boost::asio::io_context & io, Settings const& settings) -> void }); boost::asio::co_spawn( - io, - connection->connect(io, settings.host, settings.service), - [&io, &settings](std::exception_ptr e) - { + io, connection->connect(io, settings.host, settings.service), + [&io, &settings](std::exception_ptr e) { auto timer = std::make_shared(io); timer->expires_after(5s); - timer->async_wait([&io, &settings, timer](auto) { - start(io, settings); - }); - }); + timer->async_wait( + [&io, &settings, timer](auto) { start(io, settings); } + ); + } + ); } auto get_settings() -> Settings { - if (auto config_stream = std::ifstream {"config.toml"}) + if (auto config_stream = std::ifstream{"config.toml"}) { return Settings::from_stream(config_stream); } @@ -57,7 +56,7 @@ auto get_settings() -> Settings auto main() -> int { - auto const settings = get_settings(); + const auto settings = get_settings(); auto io = boost::asio::io_context{}; start(io, settings); io.run(); diff --git a/registration_thread.cpp b/registration_thread.cpp index 46cb831..bdc6086 100644 --- a/registration_thread.cpp +++ b/registration_thread.cpp @@ -9,7 +9,7 @@ #include RegistrationThread::RegistrationThread( - Connection& connection, + Connection &connection, const Settings &settings, std::shared_ptr self ) @@ -22,7 +22,10 @@ RegistrationThread::RegistrationThread( auto RegistrationThread::on_connect() -> void { connection_.send_cap_ls(); - connection_.send_pass(settings_.password); + if (not settings_.password.empty()) + { + connection_.send_pass(settings_.password); + } connection_.send_user(settings_.username, settings_.realname); connection_.send_nick(settings_.nickname); } @@ -30,7 +33,7 @@ auto RegistrationThread::on_connect() -> void auto RegistrationThread::send_req() -> void { std::string request; - std::vector want { + std::vector want{ "account-notify", "account-tag", "batch", @@ -46,11 +49,12 @@ auto RegistrationThread::send_req() -> void "solanum.chat/realhost", }; - if (settings_.sasl_mechanism == "PLAIN") { + if (not settings_.sasl_mechanism.empty()) + { want.push_back("sasl"); } - for (auto const cap : want) + for (const auto cap : want) { if (caps.contains(cap)) { @@ -73,7 +77,7 @@ auto RegistrationThread::send_req() -> void } } -auto RegistrationThread::on_msg_cap_ack(IrcMsg const& msg) -> void +auto RegistrationThread::on_msg_cap_ack(const IrcMsg &msg) -> void { auto in = std::istringstream{std::string{msg.args[2]}}; std::for_each( @@ -86,27 +90,32 @@ auto RegistrationThread::on_msg_cap_ack(IrcMsg const& msg) -> void if (outstanding.empty()) { message_handle_.disconnect(); - - if (settings_.sasl_mechanism.empty()) { + + if (settings_.sasl_mechanism.empty()) + { connection_.send_cap_end(); - } else { + } + else + { self_->start_sasl(std::make_unique(settings_.sasl_authcid, settings_.sasl_authzid, settings_.sasl_password)); connection_.sig_ircmsg.connect_extended([thread = shared_from_this()](auto &slot, auto cmd, auto &msg) { - switch (cmd) { - default: break; - case IrcCommand::RPL_SASLSUCCESS: - case IrcCommand::ERR_SASLFAIL: - thread->connection_.send_cap_end(); - slot.disconnect(); + switch (cmd) + { + default: + break; + case IrcCommand::RPL_SASLSUCCESS: + case IrcCommand::ERR_SASLFAIL: + thread->connection_.send_cap_end(); + slot.disconnect(); } }); } } } -auto RegistrationThread::on_msg_cap_ls(IrcMsg const& msg) -> void +auto RegistrationThread::on_msg_cap_ls(const IrcMsg &msg) -> void { - std::string_view const* kvs; + const std::string_view *kvs; bool last; if (3 == msg.args.size()) @@ -130,14 +139,14 @@ auto RegistrationThread::on_msg_cap_ls(IrcMsg const& msg) -> void std::istream_iterator{in}, std::istream_iterator{}, [this](std::string x) { - auto const eq = x.find('='); + const auto eq = x.find('='); if (eq == x.npos) { caps.emplace(x, std::string{}); } else { - caps.emplace(std::string{x, 0, eq}, std::string{x, eq+1, x.npos}); + caps.emplace(std::string{x, 0, eq}, std::string{x, eq + 1, x.npos}); } } ); @@ -150,17 +159,16 @@ auto RegistrationThread::on_msg_cap_ls(IrcMsg const& msg) -> void } auto RegistrationThread::start( - Connection& connection, + Connection &connection, const Settings &settings, std::shared_ptr self ) -> std::shared_ptr { - auto const thread = std::make_shared(connection, std::move(settings), std::move(self)); + const auto thread = std::make_shared(connection, std::move(settings), std::move(self)); thread->listen_for_cap_ls(); - thread->connect_handle_ = connection.sig_connect.connect([thread]() - { + thread->connect_handle_ = connection.sig_connect.connect([thread]() { thread->connect_handle_.disconnect(); thread->on_connect(); }); @@ -170,8 +178,7 @@ auto RegistrationThread::start( auto RegistrationThread::listen_for_cap_ack() -> void { - message_handle_ = connection_.sig_ircmsg.connect([thread = shared_from_this()](IrcCommand cmd, IrcMsg const& msg) - { + message_handle_ = connection_.sig_ircmsg.connect([thread = shared_from_this()](IrcCommand cmd, const IrcMsg &msg) { if (IrcCommand::CAP == cmd && msg.args.size() >= 2 && "ACK" == msg.args[1]) { thread->on_msg_cap_ack(msg); @@ -181,11 +188,15 @@ auto RegistrationThread::listen_for_cap_ack() -> void auto RegistrationThread::listen_for_cap_ls() -> void { - message_handle_ = connection_.sig_ircmsg.connect([thread = shared_from_this()](IrcCommand cmd, IrcMsg const& msg) - { + message_handle_ = connection_.sig_ircmsg.connect([thread = shared_from_this()](IrcCommand cmd, const IrcMsg &msg) { if (IrcCommand::CAP == cmd && msg.args.size() >= 2 && "LS" == msg.args[1]) { thread->on_msg_cap_ls(msg); } + else if (IrcCommand::RPL_WELCOME == cmd) + { + // Server doesn't support CAP negotiation + thread->message_handle_.disconnect(); + } }); } diff --git a/registration_thread.hpp b/registration_thread.hpp index 21969db..b808460 100644 --- a/registration_thread.hpp +++ b/registration_thread.hpp @@ -1,8 +1,8 @@ #pragma once #include "connection.hpp" -#include "settings.hpp" #include "self_thread.hpp" +#include "settings.hpp" #include #include @@ -11,7 +11,7 @@ class RegistrationThread : public std::enable_shared_from_this { - Connection& connection_; + Connection &connection_; const Settings &settings_; std::shared_ptr self_; @@ -23,21 +23,21 @@ class RegistrationThread : public std::enable_shared_from_this void; auto send_req() -> void; - auto on_msg_cap_ls(IrcMsg const& msg) -> void; - auto on_msg_cap_ack(IrcMsg const& msg) -> void; + auto on_msg_cap_ls(const IrcMsg &msg) -> void; + auto on_msg_cap_ack(const IrcMsg &msg) -> void; auto listen_for_cap_ack() -> void; auto listen_for_cap_ls() -> void; public: RegistrationThread( - Connection& connection_, + Connection &connection_, const Settings &, std::shared_ptr self ); static auto start( - Connection& connection, + Connection &connection, const Settings &, std::shared_ptr self ) -> std::shared_ptr; diff --git a/sasl_mechanism.hpp b/sasl_mechanism.hpp index 939bf8b..91eac7c 100644 --- a/sasl_mechanism.hpp +++ b/sasl_mechanism.hpp @@ -7,10 +7,6 @@ #include #include -#include "event.hpp" - -struct Connection; - class SaslMechanism { public: diff --git a/self_thread.cpp b/self_thread.cpp index dac9941..fc93c7c 100644 --- a/self_thread.cpp +++ b/self_thread.cpp @@ -9,12 +9,12 @@ using namespace std::literals; -auto SelfThread::on_welcome(IrcMsg const& irc) -> void +auto SelfThread::on_welcome(const IrcMsg &irc) -> void { nickname_ = irc.args[0]; } -auto SelfThread::on_nick(IrcMsg const& irc) -> void +auto SelfThread::on_nick(const IrcMsg &irc) -> void { if (is_my_mask(irc.source)) { @@ -22,12 +22,12 @@ auto SelfThread::on_nick(IrcMsg const& irc) -> void } } -auto SelfThread::on_umodeis(IrcMsg const& irc) -> void +auto SelfThread::on_umodeis(const IrcMsg &irc) -> void { mode_ = irc.args[1]; } -auto SelfThread::on_join(IrcMsg const& irc) -> void +auto SelfThread::on_join(const IrcMsg &irc) -> void { if (is_my_mask(irc.source)) { @@ -35,7 +35,7 @@ auto SelfThread::on_join(IrcMsg const& irc) -> void } } -auto SelfThread::on_kick(IrcMsg const& irc) -> void +auto SelfThread::on_kick(const IrcMsg &irc) -> void { if (is_my_nick(irc.args[1])) { @@ -43,7 +43,7 @@ auto SelfThread::on_kick(IrcMsg const& irc) -> void } } -auto SelfThread::on_part(IrcMsg const& irc) -> void +auto SelfThread::on_part(const IrcMsg &irc) -> void { if (is_my_mask(irc.source)) { @@ -51,12 +51,12 @@ auto SelfThread::on_part(IrcMsg const& irc) -> void } } -auto SelfThread::on_mode(IrcMsg const& irc) -> void +auto SelfThread::on_mode(const IrcMsg &irc) -> void { if (is_my_nick(irc.args[0])) { auto polarity = true; - for (char const c : irc.args[1]) + for (const char c : irc.args[1]) { switch (c) { @@ -73,7 +73,7 @@ auto SelfThread::on_mode(IrcMsg const& irc) -> void } else { - auto const ix = mode_.find(c); + const auto ix = mode_.find(c); if (ix != std::string::npos) { mode_.erase(ix, 1); @@ -87,42 +87,64 @@ auto SelfThread::on_mode(IrcMsg const& irc) -> void auto SelfThread::on_isupport(const IrcMsg &msg) -> void { - auto const hi = msg.args.size() - 1; + const auto hi = msg.args.size() - 1; for (int i = 1; i < hi; ++i) { auto &entry = msg.args[i]; // Leading minus means to stop support - if (entry.starts_with("-")) { - auto const key = std::string{entry.substr(1)}; - if (auto cursor = isupport_.find(key); cursor != isupport_.end()) { + if (entry.starts_with("-")) + { + const auto key = std::string{entry.substr(1)}; + if (auto cursor = isupport_.find(key); cursor != isupport_.end()) + { isupport_.erase(cursor); } - } else if (auto const cursor = entry.find('='); cursor != entry.npos) { - isupport_.emplace(entry.substr(0, cursor), entry.substr(cursor+1)); - } else { + } + else if (const auto cursor = entry.find('='); cursor != entry.npos) + { + isupport_.emplace(entry.substr(0, cursor), entry.substr(cursor + 1)); + } + else + { isupport_.emplace(entry, std::string{}); } } } -auto SelfThread::start(Connection& connection) -> std::shared_ptr +auto SelfThread::start(Connection &connection) -> std::shared_ptr { auto thread = std::make_shared(connection); - connection.sig_ircmsg.connect([thread](auto cmd, auto& msg) - { + connection.sig_ircmsg.connect([thread](auto cmd, auto &msg) { switch (cmd) { - case IrcCommand::JOIN: thread->on_join(msg); break; - case IrcCommand::KICK: thread->on_kick(msg); break; - case IrcCommand::MODE: thread->on_mode(msg); break; - case IrcCommand::NICK: thread->on_nick(msg); break; - case IrcCommand::PART: thread->on_part(msg); break; - case IrcCommand::RPL_ISUPPORT: thread->on_isupport(msg); break; - case IrcCommand::RPL_UMODEIS: thread->on_umodeis(msg); break; - case IrcCommand::RPL_WELCOME: thread->on_welcome(msg); break; - default: break; + case IrcCommand::JOIN: + thread->on_join(msg); + break; + case IrcCommand::KICK: + thread->on_kick(msg); + break; + case IrcCommand::MODE: + thread->on_mode(msg); + break; + case IrcCommand::NICK: + thread->on_nick(msg); + break; + case IrcCommand::PART: + thread->on_part(msg); + break; + case IrcCommand::RPL_ISUPPORT: + thread->on_isupport(msg); + break; + case IrcCommand::RPL_UMODEIS: + thread->on_umodeis(msg); + break; + case IrcCommand::RPL_WELCOME: + thread->on_welcome(msg); + break; + default: + break; } }); @@ -133,17 +155,17 @@ auto SelfThread::start(Connection& connection) -> std::shared_ptr return thread; } -auto SelfThread::get_my_nickname() const -> std::string const& +auto SelfThread::get_my_nickname() const -> const std::string & { return nickname_; } -auto SelfThread::get_my_mode() const -> std::string const& +auto SelfThread::get_my_mode() const -> const std::string & { return mode_; } -auto SelfThread::get_my_channels() const -> std::unordered_set const& +auto SelfThread::get_my_channels() const -> const std::unordered_set & { return channels_; } @@ -155,7 +177,7 @@ auto SelfThread::is_my_nick(std::string_view nick) const -> bool auto SelfThread::is_my_mask(std::string_view mask) const -> bool { - auto const bang = mask.find('!'); + const auto bang = mask.find('!'); return bang != std::string_view::npos && nickname_ == mask.substr(0, bang); } @@ -168,7 +190,8 @@ auto SelfThread::on_authenticate(const std::string_view body) -> void return; } - if (auto reply = sasl_mechanism_->step(body)) { + if (auto reply = sasl_mechanism_->step(body)) + { connection_.send_authenticate_encoded(*reply); @@ -182,7 +205,8 @@ auto SelfThread::on_authenticate(const std::string_view body) -> void auto SelfThread::start_sasl(std::unique_ptr mechanism) -> void { - if (sasl_mechanism_) { + if (sasl_mechanism_) + { connection_.send_authenticate("*"sv); // abort SASL } diff --git a/self_thread.hpp b/self_thread.hpp index 0f45f61..bdfa7c0 100644 --- a/self_thread.hpp +++ b/self_thread.hpp @@ -11,11 +11,11 @@ struct IrcMsg; /** * @brief Thread to track this connection's identity, and IRC state. - * + * */ class SelfThread { - Connection& connection_; + Connection &connection_; std::string nickname_; std::string mode_; @@ -26,27 +26,29 @@ class SelfThread std::unique_ptr sasl_mechanism_; - auto on_welcome(IrcMsg const& irc) -> void; - auto on_isupport(IrcMsg const& irc) -> void; - auto on_nick(IrcMsg const& irc) -> void; - auto on_umodeis(IrcMsg const& irc) -> void; - auto on_join(IrcMsg const& irc) -> void; - auto on_kick(IrcMsg const& irc) -> void; - auto on_part(IrcMsg const& irc) -> void; - auto on_mode(IrcMsg const& irc) -> void; + auto on_welcome(const IrcMsg &irc) -> void; + auto on_isupport(const IrcMsg &irc) -> void; + auto on_nick(const IrcMsg &irc) -> void; + auto on_umodeis(const IrcMsg &irc) -> void; + auto on_join(const IrcMsg &irc) -> void; + auto on_kick(const IrcMsg &irc) -> void; + auto on_part(const IrcMsg &irc) -> void; + auto on_mode(const IrcMsg &irc) -> void; auto on_authenticate(std::string_view) -> void; public: - SelfThread(Connection& connection) : connection_{connection} {} - static auto start(Connection&) -> std::shared_ptr; + SelfThread(Connection &connection) + : connection_{connection} + { + } + static auto start(Connection &) -> std::shared_ptr; auto start_sasl(std::unique_ptr mechanism) -> void; - auto get_my_nickname() const -> std::string const&; - auto get_my_mode() const -> std::string const&; - auto get_my_channels() const -> std::unordered_set const&; + auto get_my_nickname() const -> const std::string &; + auto get_my_mode() const -> const std::string &; + auto get_my_channels() const -> const std::unordered_set &; auto is_my_nick(std::string_view nick) const -> bool; auto is_my_mask(std::string_view nick) const -> bool; - }; diff --git a/settings.cpp b/settings.cpp index 0b24b9b..47e6377 100644 --- a/settings.cpp +++ b/settings.cpp @@ -3,12 +3,12 @@ #define TOML_ENABLE_FORMATTERS 0 #include -auto Settings::from_stream(std::istream & in) -> Settings +auto Settings::from_stream(std::istream &in) -> Settings { - auto const config = toml::parse(in); + const auto config = toml::parse(in); return Settings{ - .host = config["host"].value_or(std::string{}), - .service = config["service"].value_or(std::string{}), + .host = config["host"].value_or(std::string{}), + .service = config["service"].value_or(std::string{}), .password = config["password"].value_or(std::string{}), .username = config["username"].value_or(std::string{}), .realname = config["realname"].value_or(std::string{}), diff --git a/settings.hpp b/settings.hpp index e1c3a29..11159b0 100644 --- a/settings.hpp +++ b/settings.hpp @@ -1,7 +1,7 @@ #pragma once -#include #include +#include struct Settings { @@ -17,6 +17,5 @@ struct Settings std::string sasl_authzid; std::string sasl_password; - static auto from_stream(std::istream & in) -> Settings; + static auto from_stream(std::istream &in) -> Settings; }; - diff --git a/snote.cpp b/snote.cpp index eec93f1..196eb47 100644 --- a/snote.cpp +++ b/snote.cpp @@ -17,20 +17,19 @@ namespace { struct SnotePattern { - SnotePattern(SnoteTag tag, char const* expression, unsigned flags = 0) - : tag{tag} - , expression{expression} - , regex{expression, std::regex_constants::ECMAScript | std::regex_constants::optimize} + SnotePattern(SnoteTag tag, const char *expression, unsigned flags = 0) + : tag{tag} + , expression{expression} + , regex{expression, std::regex_constants::ECMAScript | std::regex_constants::optimize} { } SnoteTag tag; - char const* expression; + const char *expression; std::regex regex; }; -SnotePattern static const patterns[] = -{ +const SnotePattern static patterns[] = { {SnoteTag::ClientConnecting, R"(^Client connecting: ([^ ]+) \(([^@ ]+)@([^) ]+)\) \[(.*)\] \{([^ ]*)\} <([^ ]*)> \[(.*)\]$)"}, @@ -77,10 +76,10 @@ SnotePattern static const patterns[] = "^\x02([^ ]+)\x02 set vhost ([^ ]+) on the \x02MARKED\x02 account ([^ ]+).$"}, }; -static auto setup_database() -> hs_database_t* +static auto setup_database() -> hs_database_t * { - auto const n = std::size(patterns); - std::vector expressions; + const auto n = std::size(patterns); + std::vector expressions; std::vector flags(n, HS_FLAG_SINGLEMATCH); std::vector ids; @@ -93,21 +92,20 @@ static auto setup_database() -> hs_database_t* ids.push_back(i); } - hs_database_t* db; + hs_database_t *db; hs_compile_error *error; hs_platform_info_t *platform = nullptr; // target current platform switch (hs_compile_multi(expressions.data(), flags.data(), ids.data(), expressions.size(), HS_MODE_BLOCK, platform, &db, &error)) { - case HS_COMPILER_ERROR: - { - std::string msg = error->message; - hs_free_compile_error(error); - throw std::runtime_error{std::move(msg)}; - } - case HS_SUCCESS: - break; - default: - abort(); + case HS_COMPILER_ERROR: { + std::string msg = error->message; + hs_free_compile_error(error); + throw std::runtime_error{std::move(msg)}; + } + case HS_SUCCESS: + break; + default: + abort(); } return db; } @@ -118,7 +116,7 @@ SnoteCore::SnoteCore() { db_.reset(setup_database()); - hs_scratch_t* scratch = nullptr; + hs_scratch_t *scratch = nullptr; if (HS_SUCCESS != hs_alloc_scratch(db_.get(), &scratch)) { abort(); @@ -128,30 +126,29 @@ SnoteCore::SnoteCore() auto SnoteCore::match(const IrcMsg &msg) -> std::optional { - static char const* const prefix = "*** Notice -- "; + static const char *const prefix = "*** Notice -- "; - auto& args = msg.args; - if ("*" != args[0] || !args[1].starts_with(prefix)) { + auto &args = msg.args; + if ("*" != args[0] || !args[1].starts_with(prefix)) + { return std::nullopt; } - auto const message = args[1].substr(strlen(prefix)); + const auto message = args[1].substr(strlen(prefix)); unsigned match_id; - auto cb = [&match_id](unsigned id, unsigned long long, unsigned long long, unsigned) -> int - { + auto cb = [&match_id](unsigned id, unsigned long long, unsigned long long, unsigned) -> int { match_id = id; return 1; // stop scanning }; - auto const scan_result = - hs_scan( - db_.get(), - message.data(), message.size(), - 0, // no flags - scratch_.get(), - CCallback::invoke, &cb - ); + const auto scan_result = hs_scan( + db_.get(), + message.data(), message.size(), + 0, // no flags + scratch_.get(), + CCallback::invoke, &cb + ); switch (scan_result) { @@ -159,9 +156,8 @@ auto SnoteCore::match(const IrcMsg &msg) -> std::optional BOOST_LOG_TRIVIAL(warning) << "Unknown snote: " << message; return std::nullopt; - case HS_SCAN_TERMINATED: - { - auto& pattern = patterns[match_id]; + case HS_SCAN_TERMINATED: { + auto &pattern = patterns[match_id]; return SnoteMatch{pattern.tag, pattern.regex, message}; } @@ -170,14 +166,15 @@ auto SnoteCore::match(const IrcMsg &msg) -> std::optional } } -auto SnoteMatch::get_results() -> std::match_results const& +auto SnoteMatch::get_results() -> const std::match_results & { - if (auto results = std::get_if<1>(&components_)) { + if (auto results = std::get_if<1>(&components_)) + { return *results; } auto [regex, message] = std::get<0>(components_); - auto& results = components_.emplace<1>(); + auto &results = components_.emplace<1>(); if (not std::regex_match(message.begin(), message.end(), results, regex)) { // something went wrong - hyperscan disagrees with std::regex @@ -186,7 +183,7 @@ auto SnoteMatch::get_results() -> std::match_results void +auto SnoteCore::DbDeleter::operator()(hs_database_t *db) const -> void { if (HS_SUCCESS != hs_free_database(db)) { @@ -194,7 +191,7 @@ auto SnoteCore::DbDeleter::operator()(hs_database_t * db) const -> void } } -auto SnoteCore::ScratchDeleter::operator()(hs_scratch_t * scratch) const -> void +auto SnoteCore::ScratchDeleter::operator()(hs_scratch_t *scratch) const -> void { if (HS_SUCCESS != hs_free_scratch(scratch)) {