1
0
Fork 0
mirror of https://github.com/transmission/transmission synced 2025-01-01 12:35:22 +00:00
transmission/libtransmission
2022-01-18 11:20:14 -06:00
..
.clang-tidy
announce-list.cc
announce-list.h
announcer-common.h
announcer-http.cc
announcer-udp.cc fix: string leak regression when udp announces fail (#2440) 2022-01-18 11:20:14 -06:00
announcer.cc
announcer.h
bandwidth.cc
bandwidth.h
bitfield.cc
bitfield.h
block-info.cc
block-info.h
blocklist.cc
blocklist.h
cache.cc
cache.h
clients.cc
clients.h
CMakeLists.txt
completion.cc
completion.h
crypto-utils-ccrypto.cc
crypto-utils-cyassl.cc
crypto-utils-fallback.cc
crypto-utils-openssl.cc
crypto-utils-polarssl.cc
crypto-utils.cc
crypto-utils.h
crypto.cc
crypto.h
error-types.h
error.cc
error.h
fdlimit.cc
fdlimit.h
file-piece-map.cc
file-piece-map.h
file-posix.cc
file-win32.cc
file.cc
file.h
foo
handshake.cc
handshake.h
history.h
inout.cc
inout.h
interned-string.h
jsonsl.c
jsonsl.h
libt.dox
log.cc
log.h
magnet-metainfo.cc
magnet-metainfo.h
makemeta.cc
makemeta.h
mime-types.h
mime-types.js
natpmp.cc
natpmp_local.h
net.cc
net.h
peer-common.h
peer-io.cc
peer-io.h
peer-mgr-active-requests.cc
peer-mgr-active-requests.h
peer-mgr-wishlist.cc
peer-mgr-wishlist.h
peer-mgr.cc
peer-mgr.h
peer-msgs.cc
peer-msgs.h
peer-socket.h
platform-quota.cc
platform-quota.h
platform.cc
platform.h
port-forwarding.cc
port-forwarding.h
ptrarray.cc
ptrarray.h
quark.cc
quark.h
README.md
resume.cc
resume.h
rpc-server.cc
rpc-server.h
rpcimpl.cc
rpcimpl.h
session-id.cc
session-id.h
session.cc
session.h
stats.cc
stats.h
subprocess-posix.cc
subprocess-win32.cc
subprocess.h
torrent-ctor.cc
torrent-magnet.cc
torrent-magnet.h
torrent-metainfo.cc
torrent-metainfo.h
torrent.cc
torrent.h
tr-assert.cc
tr-assert.h
tr-dht.cc
tr-dht.h
tr-getopt.cc
tr-getopt.h
tr-lpd.cc
tr-lpd.h
tr-macros.h
tr-udp.cc
tr-udp.h
tr-utp.cc
tr-utp.h
transmission.h
trevent.cc
trevent.h
upnp.cc
upnp.h
utils.cc
utils.h
variant-benc.cc
variant-common.h
variant-json.cc
variant.cc
variant.h
verify.cc
verify.h
version.h.in
watchdir-common.h
watchdir-generic.cc
watchdir-inotify.cc
watchdir-kqueue.cc
watchdir-win32.cc
watchdir.cc
watchdir.h
web-utils.cc
web-utils.h
web.cc
web.h
webseed.cc
webseed.h
wildmat.c

Notes on the C-to-C++ Conversion

  • libtransmission was written in C for fifteen years, so eliminating all Cisms is nearly impossible. Modernization patches are welcomed but it won't all happen overnight. tr_strdup() and constexpr wil exist side-by-side in the codebase for the forseeable future.

  • It's so tempting to refactor all the things! Please keep modernization patches reasonably focused so that they will be easy to review.

  • Prefer std:: tools over bespoke ones. For example, use std::vector instead of tr_ptrArray. Redundant bespoke code should be removed.

  • Consider ripple effects before adding C++ into public headers. Will it break C code that #includes that header? If you think it might, consult with downstream projects to see if this is a problem for them.

Checklist for modernization of a module

NOTE:
The version in libtransmission/CMakeLists.txt is C++17.
See https://github.com/AnthonyCalandra/modern-cpp-features

This can be done in multiple smaller passes:

  1. Satisfy clang-tidy. libtransmission/.clang-tidy's list of rules should eventually be expanded to a list similar to the one in qt/.clang-tidy.
  2. Group member functions and their parent structs
    • Use namespace libtransmission
    • Split large modules into smaller groups of files in a libtransmission/<name> subdirectories, with own sub-namespace.
  3. Enums replaced with new enum class syntax. Numeric #define constants replaced with C++ const/constexpr.
  4. Memory - promote init and free functions to C++ ctors and dtors, and ensure it is only managed with new/delete
  5. Owned memory - promote simple pointer fields owning their data to smart pointers (unique_ptr, shared_ptr, vector, string)

Detailed Steps

  1. Satisfy clang-tidy warnings

    • Change C includes to C++ wraps, example: <string.h> becomes and update calls to standard library to use std:: namespace prefix. This clearly delineates the border between std library and transmission. Headers must be sorted alphabetically.
    • Headers which are used conditionally based on some #ifdef in the code, should also have same #ifdef in the include section.
    • Revisit type warnings, int vs unsigned int. Sizes and counts should use size_t type where this does not break external API declarations. Ideally change that too.
  2. Move and group code together.

    • Move member functions into structs. To minimize code churn, create function forward declarations inside structs, and give struct_name:: prefixes to the functions.
      typedef struct {
          int field;
      } foo;
      int foo_blep(struct foo *f) {
          return f->field;
      }
      
      becomes:
      struct foo {
          int field;
          void blep(); 
      };
      int foo::blep() {
          return this->field; 
      }
      
    • For functions taking const pointer, add const after the function prototype: int blep() const like so.
    • For structs used by other modules, struct definitions should relocate to internal *-common.h header files.
    • Split large files into sub-modules sharing own separate sub-namespace and sitting in a subdirectory under libtransmission/.
    • Some externally invoked functions must either not move OR have extern "C" adapter functions.
  3. Enums promoted to enum class and given a type:

    enum { A, B, C };
    

    becomes

    enum: int { A, B, C };        // unscoped, use A, B, C
    enum MyEnum: int { A, B, C }; // unscoped, use A, B, C
    // OR wrap into a scope -
    enum struct MyEnum: int { A, B, C }; // scoped, use MyEnum::A
    enum class MyEnum: int { A, B, C };  // scoped, use MyEnum::A
    

    this will make all values of enum to have that numeric type.

  4. Numeric/bool #define constants should be replaced with C++ const/constexpr.

  5. Memory management:

    • Prefer constructors and destructors vs manual construction and destruction. But when doing so must ensure that the struct is never constructed using C malloc/free, but must use C++ new/delete.
    • Avoid using std::memset on a new struct. It is allowed in C, and C++ struct but will destroy virtual table on a C++ class. Use field initializers in C++.
  6. Owned memory:

    • If destructor deletes something, it means it was owned. Promote that field to owning type (vector, unique_ptr, shared_ptr or string).