]> PatchyGit - patchyircd.git/commitdiff
map: make stringset return std::string
authorEgor <egor@patchysicp.xyz>
Tue, 3 Feb 2026 14:49:51 +0000 (16:49 +0200)
committerEgor <egor@patchysicp.xyz>
Tue, 3 Feb 2026 14:49:51 +0000 (16:49 +0200)
src/irc.cpp
src/ircfmt.cpp
src/ircfmt.hpp
src/map.hpp
src/util.cpp
src/util.hpp

index 5ce7e8b..384358a 100644 (file)
@@ -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);
index 2c9d15d..63b272c 100644 (file)
@@ -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
 {
index c1bb2a0..56ad82c 100644 (file)
@@ -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
index ff8728b..4625b8e 100644 (file)
@@ -222,10 +222,10 @@ private:
        }
        using value_to_void_type = decltype(value_to_void(std::declval<T>()));
 
-       constexpr T void_to_value(void *p) noexcept requires (std::same_as<T, Client*> || std::same_as<T, Channel*>) {
+       static constexpr T void_to_value(void *p) noexcept requires (std::same_as<T, Client*> || std::same_as<T, Channel*>) {
                return static_cast<T>(p);
        }
-       constexpr std::string_view void_to_value(void *p) noexcept requires std::same_as<T, std::string> {
+       static constexpr std::string_view void_to_value(void *p) noexcept requires std::same_as<T, std::string> {
                return static_cast<char *>(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<iterator>);
index 525ecf6..28497b6 100644 (file)
@@ -38,6 +38,11 @@ void append_strf(std::vector<char> *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<char>(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;
index f4e04f3..668c868 100644 (file)
@@ -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;