|
| 1 | +From daa3e1ead791bc58208043cfc4595ba1a78cdd34 Mon Sep 17 00:00:00 2001 |
| 2 | +From: Jakub Jelinek <jakub@redhat.com> |
| 3 | +Date: Fri, 21 Nov 2025 16:25:58 +0100 |
| 4 | +Subject: [PATCH] libcody: Make it buildable by C++11 to C++26 |
| 5 | + |
| 6 | +The following builds with -std=c++11 and c++14 and c++17 and c++20 and c++23 |
| 7 | +and c++26. |
| 8 | + |
| 9 | +I see the u8 string literals are mixed e.g. with strerror, so in |
| 10 | +-fexec-charset=IBM1047 there will still be garbage, so am not 100% sure if |
| 11 | +the u8 literals everywhere are worth it either. |
| 12 | + |
| 13 | +2025-11-21 Jakub Jelinek <jakub@redhat.com> |
| 14 | + |
| 15 | + * cody.hh (S2C): For __cpp_char8_t >= 201811 use char8_t instead of |
| 16 | + char in argument type. |
| 17 | + (MessageBuffer::Space): Revert 2025-11-15 change. |
| 18 | + (MessageBuffer::Append): For __cpp_char8_t >= 201811 add overload |
| 19 | + with char8_t const * type of first argument. |
| 20 | + (Packet::Packet): Similarly for first argument. |
| 21 | + * client.cc (CommunicationError, Client::ProcessResponse, |
| 22 | + Client::Connect, ConnectResponse, PathnameResponse, OKResponse, |
| 23 | + IncludeTranslateResponse): Cast u8 string literals to (const char *) |
| 24 | + where needed. |
| 25 | + * server.cc (Server::ProcessRequests, ConnectRequest): Likewise. |
| 26 | + |
| 27 | +(cherry picked from commit 07a767c7a50d1daae8ef7d4aba73fe53ad40c0b7) |
| 28 | +--- |
| 29 | + libcody/client.cc | 36 +++++++++++++++++++----------------- |
| 30 | + libcody/cody.hh | 22 ++++++++++++++++++++++ |
| 31 | + libcody/server.cc | 28 ++++++++++++++-------------- |
| 32 | + 3 files changed, 55 insertions(+), 31 deletions(-) |
| 33 | + |
| 34 | +diff --git a/libcody/client.cc b/libcody/client.cc |
| 35 | +index ae69d190cb7..147fecdbe50 100644 |
| 36 | +--- a/libcody/client.cc |
| 37 | ++++ b/libcody/client.cc |
| 38 | +@@ -97,7 +97,7 @@ int Client::CommunicateWithServer () |
| 39 | + |
| 40 | + static Packet CommunicationError (int err) |
| 41 | + { |
| 42 | +- std::string e {u8"communication error:"}; |
| 43 | ++ std::string e {(const char *) u8"communication error:"}; |
| 44 | + e.append (strerror (err)); |
| 45 | + |
| 46 | + return Packet (Client::PC_ERROR, std::move (e)); |
| 47 | +@@ -110,33 +110,34 @@ Packet Client::ProcessResponse (std::vector<std::string> &words, |
| 48 | + { |
| 49 | + if (e == EINVAL) |
| 50 | + { |
| 51 | +- std::string msg (u8"malformed string '"); |
| 52 | ++ std::string msg ((const char *) u8"malformed string '"); |
| 53 | + msg.append (words[0]); |
| 54 | +- msg.append (u8"'"); |
| 55 | ++ msg.append ((const char *) u8"'"); |
| 56 | + return Packet (Client::PC_ERROR, std::move (msg)); |
| 57 | + } |
| 58 | + else |
| 59 | +- return Packet (Client::PC_ERROR, u8"missing response"); |
| 60 | ++ return Packet (Client::PC_ERROR, (const char *) u8"missing response"); |
| 61 | + } |
| 62 | + |
| 63 | + Assert (!words.empty ()); |
| 64 | +- if (words[0] == u8"ERROR") |
| 65 | ++ if (words[0] == (const char *) u8"ERROR") |
| 66 | + return Packet (Client::PC_ERROR, |
| 67 | +- words.size () == 2 ? words[1]: u8"malformed error response"); |
| 68 | ++ words.size () == 2 ? words[1] |
| 69 | ++ : (const char *) u8"malformed error response"); |
| 70 | + |
| 71 | + if (isLast && !read.IsAtEnd ()) |
| 72 | + return Packet (Client::PC_ERROR, |
| 73 | +- std::string (u8"unexpected extra response")); |
| 74 | ++ std::string ((const char *) u8"unexpected extra response")); |
| 75 | + |
| 76 | + Assert (code < Detail::RC_HWM); |
| 77 | + Packet result (responseTable[code] (words)); |
| 78 | + result.SetRequest (code); |
| 79 | + if (result.GetCode () == Client::PC_ERROR && result.GetString ().empty ()) |
| 80 | + { |
| 81 | +- std::string msg {u8"malformed response '"}; |
| 82 | ++ std::string msg {(const char *) u8"malformed response '"}; |
| 83 | + |
| 84 | + read.LexedLine (msg); |
| 85 | +- msg.append (u8"'"); |
| 86 | ++ msg.append ((const char *) u8"'"); |
| 87 | + result.GetString () = std::move (msg); |
| 88 | + } |
| 89 | + else if (result.GetCode () == Client::PC_CONNECT) |
| 90 | +@@ -199,7 +200,7 @@ Packet Client::Connect (char const *agent, char const *ident, |
| 91 | + size_t alen, size_t ilen) |
| 92 | + { |
| 93 | + write.BeginLine (); |
| 94 | +- write.AppendWord (u8"HELLO"); |
| 95 | ++ write.AppendWord ((const char *) u8"HELLO"); |
| 96 | + write.AppendInteger (Version); |
| 97 | + write.AppendWord (agent, true, alen); |
| 98 | + write.AppendWord (ident, true, ilen); |
| 99 | +@@ -211,7 +212,8 @@ Packet Client::Connect (char const *agent, char const *ident, |
| 100 | + // HELLO $version $agent [$flags] |
| 101 | + Packet ConnectResponse (std::vector<std::string> &words) |
| 102 | + { |
| 103 | +- if (words[0] == u8"HELLO" && (words.size () == 3 || words.size () == 4)) |
| 104 | ++ if (words[0] == (const char *) u8"HELLO" |
| 105 | ++ && (words.size () == 3 || words.size () == 4)) |
| 106 | + { |
| 107 | + char *eptr; |
| 108 | + unsigned long val = strtoul (words[1].c_str (), &eptr, 10); |
| 109 | +@@ -247,7 +249,7 @@ Packet Client::ModuleRepo () |
| 110 | + // PATHNAME $dir | ERROR |
| 111 | + Packet PathnameResponse (std::vector<std::string> &words) |
| 112 | + { |
| 113 | +- if (words[0] == u8"PATHNAME" && words.size () == 2) |
| 114 | ++ if (words[0] == (const char *) u8"PATHNAME" && words.size () == 2) |
| 115 | + return Packet (Client::PC_PATHNAME, std::move (words[1])); |
| 116 | + |
| 117 | + return Packet (Client::PC_ERROR, u8""); |
| 118 | +@@ -256,7 +258,7 @@ Packet PathnameResponse (std::vector<std::string> &words) |
| 119 | + // OK or ERROR |
| 120 | + Packet OKResponse (std::vector<std::string> &words) |
| 121 | + { |
| 122 | +- if (words[0] == u8"OK") |
| 123 | ++ if (words[0] == (const char *) u8"OK") |
| 124 | + return Packet (Client::PC_OK); |
| 125 | + else |
| 126 | + return Packet (Client::PC_ERROR, |
| 127 | +@@ -319,11 +321,11 @@ Packet Client::IncludeTranslate (char const *include, Flags flags, size_t ilen) |
| 128 | + // PATHNAME $cmifile |
| 129 | + Packet IncludeTranslateResponse (std::vector<std::string> &words) |
| 130 | + { |
| 131 | +- if (words[0] == u8"BOOL" && words.size () == 2) |
| 132 | ++ if (words[0] == (const char *) u8"BOOL" && words.size () == 2) |
| 133 | + { |
| 134 | +- if (words[1] == u8"FALSE") |
| 135 | +- return Packet (Client::PC_BOOL, 0); |
| 136 | +- else if (words[1] == u8"TRUE") |
| 137 | ++ if (words[1] == (const char *) u8"FALSE") |
| 138 | ++ return Packet (Client::PC_BOOL); |
| 139 | ++ else if (words[1] == (const char *) u8"TRUE") |
| 140 | + return Packet (Client::PC_BOOL, 1); |
| 141 | + else |
| 142 | + return Packet (Client::PC_ERROR, u8""); |
| 143 | +diff --git a/libcody/cody.hh b/libcody/cody.hh |
| 144 | +index 789ce9e70b7..93bce93aa94 100644 |
| 145 | +--- a/libcody/cody.hh |
| 146 | ++++ b/libcody/cody.hh |
| 147 | +@@ -47,12 +47,21 @@ namespace Detail { |
| 148 | + |
| 149 | + // C++11 doesn't have utf8 character literals :( |
| 150 | + |
| 151 | ++#if __cpp_char8_t >= 201811 |
| 152 | ++template<unsigned I> |
| 153 | ++constexpr char S2C (char8_t const (&s)[I]) |
| 154 | ++{ |
| 155 | ++ static_assert (I == 2, "only single octet strings may be converted"); |
| 156 | ++ return s[0]; |
| 157 | ++} |
| 158 | ++#else |
| 159 | + template<unsigned I> |
| 160 | + constexpr char S2C (char const (&s)[I]) |
| 161 | + { |
| 162 | + static_assert (I == 2, "only single octet strings may be converted"); |
| 163 | + return s[0]; |
| 164 | + } |
| 165 | ++#endif |
| 166 | + |
| 167 | + /// Internal buffering class. Used to concatenate outgoing messages |
| 168 | + /// and Lex incoming ones. |
| 169 | +@@ -123,6 +132,13 @@ public: |
| 170 | + Space (); |
| 171 | + Append (str, maybe_quote, len); |
| 172 | + } |
| 173 | ++#if __cpp_char8_t >= 201811 |
| 174 | ++ void AppendWord (char8_t const *str, bool maybe_quote = false, |
| 175 | ++ size_t len = ~size_t (0)) |
| 176 | ++ { |
| 177 | ++ AppendWord ((const char *) str, maybe_quote, len); |
| 178 | ++ } |
| 179 | ++#endif |
| 180 | + /// Add a word as with AppendWord |
| 181 | + /// @param str the string to append |
| 182 | + /// @param maybe_quote string might need quoting, as for Append |
| 183 | +@@ -264,6 +280,12 @@ public: |
| 184 | + : string (s), cat (STRING), code (c) |
| 185 | + { |
| 186 | + } |
| 187 | ++#if __cpp_char8_t >= 201811 |
| 188 | ++ Packet (unsigned c, const char8_t *s) |
| 189 | ++ : string ((const char *) s), cat (STRING), code (c) |
| 190 | ++ { |
| 191 | ++ } |
| 192 | ++#endif |
| 193 | + Packet (unsigned c, std::vector<std::string> &&v) |
| 194 | + : vector (std::move (v)), cat (VECTOR), code (c) |
| 195 | + { |
| 196 | +diff --git a/libcody/server.cc b/libcody/server.cc |
| 197 | +index e2fa069bb93..c18469fae84 100644 |
| 198 | +--- a/libcody/server.cc |
| 199 | ++++ b/libcody/server.cc |
| 200 | +@@ -36,12 +36,12 @@ static RequestPair |
| 201 | + const requestTable[Detail::RC_HWM] = |
| 202 | + { |
| 203 | + // Same order as enum RequestCode |
| 204 | +- RequestPair {u8"HELLO", nullptr}, |
| 205 | +- RequestPair {u8"MODULE-REPO", ModuleRepoRequest}, |
| 206 | +- RequestPair {u8"MODULE-EXPORT", ModuleExportRequest}, |
| 207 | +- RequestPair {u8"MODULE-IMPORT", ModuleImportRequest}, |
| 208 | +- RequestPair {u8"MODULE-COMPILED", ModuleCompiledRequest}, |
| 209 | +- RequestPair {u8"INCLUDE-TRANSLATE", IncludeTranslateRequest}, |
| 210 | ++ RequestPair {(const char *) u8"HELLO", nullptr}, |
| 211 | ++ RequestPair {(const char *) u8"MODULE-REPO", ModuleRepoRequest}, |
| 212 | ++ RequestPair {(const char *) u8"MODULE-EXPORT", ModuleExportRequest}, |
| 213 | ++ RequestPair {(const char *) u8"MODULE-IMPORT", ModuleImportRequest}, |
| 214 | ++ RequestPair {(const char *) u8"MODULE-COMPILED", ModuleCompiledRequest}, |
| 215 | ++ RequestPair {(const char *) u8"INCLUDE-TRANSLATE", IncludeTranslateRequest}, |
| 216 | + }; |
| 217 | + } |
| 218 | + |
| 219 | +@@ -135,21 +135,21 @@ void Server::ProcessRequests (void) |
| 220 | + std::string msg; |
| 221 | + |
| 222 | + if (err > 0) |
| 223 | +- msg = u8"error processing '"; |
| 224 | ++ msg = (const char *) u8"error processing '"; |
| 225 | + else if (ix >= Detail::RC_HWM) |
| 226 | +- msg = u8"unrecognized '"; |
| 227 | ++ msg = (const char *) u8"unrecognized '"; |
| 228 | + else if (IsConnected () && ix == Detail::RC_CONNECT) |
| 229 | +- msg = u8"already connected '"; |
| 230 | ++ msg = (const char *) u8"already connected '"; |
| 231 | + else if (!IsConnected () && ix != Detail::RC_CONNECT) |
| 232 | +- msg = u8"not connected '"; |
| 233 | ++ msg = (const char *) u8"not connected '"; |
| 234 | + else |
| 235 | +- msg = u8"malformed '"; |
| 236 | ++ msg = (const char *) u8"malformed '"; |
| 237 | + |
| 238 | + read.LexedLine (msg); |
| 239 | +- msg.append (u8"'"); |
| 240 | ++ msg.append ((const char *) u8"'"); |
| 241 | + if (err > 0) |
| 242 | + { |
| 243 | +- msg.append (u8" "); |
| 244 | ++ msg.append ((const char *) u8" "); |
| 245 | + msg.append (strerror (err)); |
| 246 | + } |
| 247 | + resolver->ErrorResponse (this, std::move (msg)); |
| 248 | +@@ -176,7 +176,7 @@ Resolver *ConnectRequest (Server *s, Resolver *r, |
| 249 | + return nullptr; |
| 250 | + |
| 251 | + if (words.size () == 3) |
| 252 | +- words.emplace_back (u8""); |
| 253 | ++ words.emplace_back ((const char *) u8""); |
| 254 | + unsigned version = ParseUnsigned (words[1]); |
| 255 | + if (version == ~0u) |
| 256 | + return nullptr; |
| 257 | +-- |
| 258 | +2.53.0 |
| 259 | + |
0 commit comments