From 76eabf76a4bed9acaa45e6e4ba6c800d0007d586 Mon Sep 17 00:00:00 2001 From: Egor Date: Tue, 3 Feb 2026 16:49:51 +0200 Subject: [PATCH] map: make stringset return std::string --- src/irc.cpp | 18 +++++++++--------- src/ircfmt.cpp | 29 ++++++++++++++--------------- src/ircfmt.hpp | 16 ++++++++-------- src/map.hpp | 12 ++++++------ src/util.cpp | 40 +++++++++++++++++++++++----------------- src/util.hpp | 2 +- 6 files changed, 61 insertions(+), 56 deletions(-) diff --git a/src/irc.cpp b/src/irc.cpp index 5ce7e8b..384358a 100644 --- a/src/irc.cpp +++ b/src/irc.cpp @@ -101,7 +101,7 @@ const char *format_umodes(Client *cl) { } static int match_list(Client *cl, stringset &list) { - for (auto key : list) + for (auto& key : list) if (irc_glob(cl->nuh, key)) return 1; return 0; @@ -952,33 +952,33 @@ privmsg_notice_common: any = 1; } if (all || !strcmp(args[1], "+b") || !strcmp(args[1], "b")) { - for (auto key : chan->listb) + for (auto& key : chan->listb) rpl_banlist(client, chan, key), sendbuf(client); rpl_endofbanlist(client, chan), sendbuf(client); any = 1; } if (all || !strcmp(args[1], "+e") || !strcmp(args[1], "e")) { - for (auto key : chan->liste) + for (auto& key : chan->liste) rpl_exceptlist(client, chan, key), sendbuf(client); rpl_endofexceptlist(client, chan), sendbuf(client); any = 1; } if (all || !strcmp(args[1], "+I") || !strcmp(args[1], "I")) { - for (auto key : chan->listI) + for (auto& key : chan->listI) rpl_invexlist(client, chan, key), sendbuf(client); rpl_endofinvexlist(client, chan), sendbuf(client); any = 1; } if (all || !strcmp(args[1], "+q") || !strcmp(args[1], "q")) { - for (auto key : chan->listq) + for (const auto& key : chan->listq) rpl_quietlist(client, chan, key), sendbuf(client); rpl_endofquietlist(client, chan), sendbuf(client); any = 1; } if (all || !strcmp(args[1], "+w") || !strcmp(args[1], "w")) { - for (auto key : chan->listwo) + for (const auto& key : chan->listwo) rpl_accesslist(client, chan, 'o', key), sendbuf(client); - for (auto key : chan->listwv) + for (const auto& key : chan->listwv) rpl_accesslist(client, chan, 'v', key), sendbuf(client); rpl_endofaccesslist(client, chan), sendbuf(client); any = 1; @@ -1173,12 +1173,12 @@ privmsg_notice_common: client->monitor.clear(); break; case 'L': - for (auto key : client->monitor) + for (auto& key : client->monitor) rpl_monlist(client, key), sendbuf(client); rpl_endofmonlist(client), sendbuf(client); break; case 'S': - for (auto key : client->monitor) { + for (auto& key : client->monitor) { Client *cl = client_map.get(key); if (cl) rpl_mononline(client, cl), sendbuf(client); diff --git a/src/ircfmt.cpp b/src/ircfmt.cpp index 2c9d15d..63b272c 100644 --- a/src/ircfmt.cpp +++ b/src/ircfmt.cpp @@ -443,17 +443,17 @@ void rpl_inviting(Client *client, Client *cl, Channel *chan) // 341 { copy_strf(&databuf, ":%s 341 %s %s %s\r\n", hostname, client->nick, cl->nick, chan->name); } -void rpl_invexlist(Client *client, Channel *chan, const char *mask) // 346 +void rpl_invexlist(Client *client, Channel *chan, std::string_view mask) // 346 { - copy_strf(&databuf, ":%s 346 %s %s %s\r\n", hostname, client->nick, chan->name, mask); + copy_strf(&databuf, ":%s 346 %s %s %.*s\r\n", hostname, client->nick, chan->name, (int)mask.size(), mask.data()); } void rpl_endofinvexlist(Client *client, Channel *chan) // 347 { copy_strf(&databuf, ":%s 347 %s %s :End of Channel Invite Exception List\r\n", hostname, client->nick, chan->name); } -void rpl_exceptlist(Client *client, Channel *chan, const char *mask) // 348 +void rpl_exceptlist(Client *client, Channel *chan, std::string_view mask) // 348 { - copy_strf(&databuf, ":%s 348 %s %s %s\r\n", hostname, client->nick, chan->name, mask); + copy_strf(&databuf, ":%s 348 %s %s %.*s\r\n", hostname, client->nick, chan->name, (int)mask.size(), mask.data()); } void rpl_endofexceptlist(Client *client, Channel *chan) // 349 { @@ -494,9 +494,9 @@ void rpl_endofnames(Client *client, const char *channel) // 366 } // 364 RPL_LINKS // 365 RPL_ENDOFLINKS -void rpl_banlist(Client *client, Channel *chan, const char *mask) // 367 +void rpl_banlist(Client *client, Channel *chan, std::string_view mask) // 367 { - copy_strf(&databuf, ":%s 367 %s %s %s\r\n", hostname, client->nick, chan->name, mask); + copy_strf(&databuf, ":%s 367 %s %s %.*s\r\n", hostname, client->nick, chan->name, (int)mask.size(), mask.data()); } void rpl_endofbanlist(Client *client, Channel *chan) // 368 { @@ -702,9 +702,9 @@ void rpl_endofhelp(Client *client) // 706 copy_strf(&databuf, ":%s 706 %s * :End of /HELP\r\n", hostname, client->nick); } // 723 ERR_NOPRIVS -void rpl_quietlist(Client *client, Channel *chan, const char *mask) // 728 +void rpl_quietlist(Client *client, Channel *chan, std::string_view mask) // 728 { - copy_strf(&databuf, ":%s 728 %s %s q %s\r\n", hostname, client->nick, chan->name, mask); + copy_strf(&databuf, ":%s 728 %s %s q %.*s\r\n", hostname, client->nick, chan->name, (int)mask.size(), mask.data()); } void rpl_endofquietlist(Client *client, Channel *chan) // 729 { @@ -714,13 +714,13 @@ void rpl_mononline(Client *client, Client *cl) // 730 { copy_strf(&databuf, ":%s 730 %s :%s!%s@%s\r\n", hostname, client ? client->nick : "*", cl->nick, cl->username, cl->hostname); } -void rpl_monoffline(Client *client, const char *nick) // 731 +void rpl_monoffline(Client *client, std::string_view nick) // 731 { - copy_strf(&databuf, ":%s 731 %s :%s\r\n", hostname, client ? client->nick : "*", nick); + copy_strf(&databuf, ":%s 731 %s :%.*s\r\n", hostname, client ? client->nick : "*", (int)nick.size(), nick.data()); } -void rpl_monlist(Client *client, const char *nick) // 732 +void rpl_monlist(Client *client, std::string_view nick) // 732 { - copy_strf(&databuf, ":%s 732 %s :%s\r\n", hostname, client->nick, nick); + copy_strf(&databuf, ":%s 732 %s :%.*s\r\n", hostname, client->nick, (int)nick.size(), nick.data()); } void rpl_endofmonlist(Client *client) // 733 { @@ -765,10 +765,9 @@ void rpl_saslmechs(void) // 908 { copy_strf(&databuf, ":%s 908 * PLAIN,EXTERNAL :are available SASL mechanisms\r\n", hostname); } -void rpl_accesslist(Client *client, Channel *chan, char mode, const char *mask) // 910 +void rpl_accesslist(Client *client, Channel *chan, char mode, std::string_view mask) // 910 { - char modes[2] = {mode,0}; - copy_strf(&databuf, ":%s 910 %s %s %s:%s\r\n", hostname, client->nick, chan->name, modes, mask); + copy_strf(&databuf, ":%s 910 %s %s %c:%.*s\r\n", hostname, client->nick, chan->name, mode, (int)mask.size(), mask.data()); } void rpl_endofaccesslist(Client *client, Channel *chan) // 911 { diff --git a/src/ircfmt.hpp b/src/ircfmt.hpp index c1bb2a0..56ad82c 100644 --- a/src/ircfmt.hpp +++ b/src/ircfmt.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2022-2025 Egor +// Copyright (c) 2022-2026 Egor // SPDX-License-Identifier: GPL-2.0-or-later #ifndef IRCFMT_H_ #define IRCFMT_H_ @@ -75,16 +75,16 @@ void rpl_invitelist(Client *client, Channel *chan); // 336 void rpl_endofinvitelist(Client *client); // 337 void rpl_whoisactually(Client *client, Client *cl); // 338 void rpl_inviting(Client *client, Client *cl, Channel *chan); // 341 -void rpl_invexlist(Client *client, Channel *chan, const char *mask); // 346 +void rpl_invexlist(Client *client, Channel *chan, std::string_view mask); // 346 void rpl_endofinvexlist(Client *client, Channel *chan); // 347 -void rpl_exceptlist(Client *client, Channel *chan, const char *mask); // 348 +void rpl_exceptlist(Client *client, Channel *chan, std::string_view mask); // 348 void rpl_endofexceptlist(Client *client, Channel *chan); // 349 void rpl_version(Client *client, const char *ver, const char *comments); // 351 int rpl_namreply(Client *client, Channel *chan, Client *cl); // 353 void rpl_endofnames(Client *client, const char *channel); // 366 // 364 RPL_LINKS // 365 RPL_ENDOFLINKS -void rpl_banlist(Client *client, Channel *chan, const char *mask); // 367 +void rpl_banlist(Client *client, Channel *chan, std::string_view mask); // 367 void rpl_endofbanlist(Client *client, Channel *chan); // 368 // 369 RPL_ENDOFWHOWAS // 371 RPL_INFO @@ -142,11 +142,11 @@ void rpl_helpstart(Client *client); // 704 void rpl_helptxt(Client *client, const char *line); // 705 void rpl_endofhelp(Client *client); // 706 // 723 ERR_NOPRIVS -void rpl_quietlist(Client *client, Channel *chan, const char *mask); // 728 +void rpl_quietlist(Client *client, Channel *chan, std::string_view mask); // 728 void rpl_endofquietlist(Client *client, Channel *chan); // 729 void rpl_mononline(Client *client, Client *cl); // 730 -void rpl_monoffline(Client *client, const char *nick); // 731 -void rpl_monlist(Client *client, const char *nick); // 732 +void rpl_monoffline(Client *client, std::string_view nick); // 731 +void rpl_monlist(Client *client, std::string_view nick); // 732 void rpl_endofmonlist(Client *client); // 733 void rpl_monlistfull(Client *client, int limit, const char *targets); // 734 void rpl_loggedin(Client *client); // 900 @@ -158,6 +158,6 @@ void err_sasltoolong(void); // 905 void err_saslaborted(void); // 906 void err_saslalready(void); // 907 void rpl_saslmechs(void); // 908 -void rpl_accesslist(Client *client, Channel *chan, char mode, const char *mask); // 910 +void rpl_accesslist(Client *client, Channel *chan, char mode, std::string_view mask); // 910 void rpl_endofaccesslist(Client *client, Channel *chan); // 911 #endif diff --git a/src/map.hpp b/src/map.hpp index ff8728b..4625b8e 100644 --- a/src/map.hpp +++ b/src/map.hpp @@ -222,10 +222,10 @@ private: } using value_to_void_type = decltype(value_to_void(std::declval())); - constexpr T void_to_value(void *p) noexcept requires (std::same_as || std::same_as) { + static constexpr T void_to_value(void *p) noexcept requires (std::same_as || std::same_as) { return static_cast(p); } - constexpr std::string_view void_to_value(void *p) noexcept requires std::same_as { + static constexpr std::string_view void_to_value(void *p) noexcept requires std::same_as { return static_cast(p); } public: @@ -257,16 +257,16 @@ public: using value_type = T; struct iterator { using iterator_category = std::bidirectional_iterator_tag; - using value_type = value_to_void_type; + using value_type = T; using difference_type = ptrdiff_t; - using pointer = void; - using reference = value_to_void_type; + using pointer = const T*; + using reference = const T&; iterator &operator++() { ++ptr; return *this; } iterator operator++(int) { auto it = *this; ++ptr; return it; } iterator &operator--() { --ptr; return *this; } iterator operator--(int) { auto it = *this; --ptr; return it; } bool operator==(const iterator& other) const = default; - reference operator*() const { return value_to_void(*ptr); } + reference operator*() const { return *ptr; } decltype(m)::iterator ptr; }; static_assert(std::bidirectional_iterator); diff --git a/src/util.cpp b/src/util.cpp index 525ecf6..28497b6 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -38,6 +38,11 @@ void append_strf(std::vector *v, const char *s, ...) { const char *c = va_arg(ap, const char *); append_str(v, c ? c : "(null)"); s = end + 2; + } else if (end[1] == 's') { // %s + append_strn(v, s, end-s); + char c = static_cast(va_arg(ap, int)); + append_strn(v, &c, 1); + s = end + 2; } else if (end[1] == 'u') { // %u append_strn(v, s, end-s); unsigned c = va_arg(ap, unsigned); @@ -85,42 +90,43 @@ void set_time(time_t t) { } /* https://research.swtch.com/glob */ -int irc_glob(const char *key, const char *mask) +int irc_glob(std::string_view key, std::string_view mask) { - const char *key2 = 0, *mask2 = 0; - while (*key || *mask) { - if (*mask) { - switch (*mask) { + std::string_view key2, mask2; + while (!key.empty() || !mask.empty()) { + if (!mask.empty()) { + switch (mask.front()) { case '\\': - if (*key == *mask) { - key++, mask++; - if (!*mask) + if (key.front() == mask.front()) { + key.remove_prefix(1), mask.remove_prefix(1); + if (mask.empty()) continue; - if (*key == *mask) { - key++, mask++; + if (key.front() == mask.front()) { + key.remove_prefix(1), mask.remove_prefix(1); continue; } } break; default: - if (*key == *mask) { - key++, mask++; + if (key.front() == mask.front()) { + key.remove_prefix(1), mask.remove_prefix(1); continue; } break; case '?': - if (*key) { - key++, mask++; + if (!key.empty()) { + key.remove_prefix(1), mask.remove_prefix(1); continue; } break; case '*': - key2 = *key ? key + 1 : 0; - mask2 = mask++; + key2 = !key.empty() ? key.substr(1) : std::string_view(); + mask2 = mask; + mask.remove_prefix(1); continue; } } - if (key2) { + if (key2.data()) { key = key2; mask = mask2; continue; diff --git a/src/util.hpp b/src/util.hpp index f4e04f3..668c868 100644 --- a/src/util.hpp +++ b/src/util.hpp @@ -25,7 +25,7 @@ void stringlower(char *s); char *mystrdup(const char *s); time_t get_time(void); void set_time(time_t t); -int irc_glob(const char *key, const char *mask); +int irc_glob(std::string_view key, std::string_view mask); extern const char *datadir; const char *getdatafile(const char *fn); extern const char *luadir; -- 2.56.0