merged RC_1_2 into RC_2_0

This commit is contained in:
arvidn
2020-12-20 20:20:39 +01:00
17 changed files with 355 additions and 158 deletions

View File

@ -15,9 +15,12 @@ jobs:
- name: checkout
uses: actions/checkout@v2.3.3
- name: update package lists
run: |
sudo apt update
- name: install dependencies
run: |
sudo apt-get update
sudo apt install python-docutils python-pygments python-pil gsfonts inkscape icoutils graphviz hunspell imagemagick
python -m pip install aafigure
~/.local/bin/aafigure --version

View File

@ -22,6 +22,10 @@ jobs:
with:
submodules: recursive
- name: update package lists
run: |
sudo apt update
- name: install boost
run: |
sudo apt install libboost-tools-dev libboost-dev libboost-system-dev
@ -57,6 +61,10 @@ jobs:
with:
submodules: recursive
- name: update package lists
run: |
sudo apt update
- name: install boost
run: |
sudo apt install libboost-tools-dev libboost-dev libboost-system-dev
@ -79,6 +87,10 @@ jobs:
with:
submodules: recursive
- name: update package lists
run: |
sudo apt update
- name: install boost
run: |
sudo apt install libboost-tools-dev libboost-dev libboost-system-dev
@ -100,6 +112,10 @@ jobs:
with:
submodules: recursive
- name: update package lists
run: |
sudo apt update
- name: install clang-tidy
run: sudo apt install clang-tidy
@ -129,6 +145,10 @@ jobs:
with:
submodules: recursive
- name: update package lists
run: |
sudo apt update
- name: install boost
run: |
sudo apt install libboost-tools-dev libboost-dev libboost-system-dev
@ -155,6 +175,10 @@ jobs:
with:
submodules: recursive
- name: update package lists
run: |
sudo apt update
- name: install boost
run: |
sudo apt install libboost-tools-dev libboost-dev libboost-system-dev
@ -177,6 +201,10 @@ jobs:
with:
submodules: recursive
- name: update package lists
run: |
sudo apt update
- name: install boost
run: |
sudo apt install libboost-tools-dev libboost-python-dev libboost-dev libboost-system-dev
@ -207,9 +235,12 @@ jobs:
with:
submodules: recursive
- name: update package lists
run: |
sudo apt update
- name: install boost
run: |
sudo apt-get update
sudo apt install libboost-tools-dev libboost-python-dev libboost-dev libboost-system-dev
sudo apt install python-docutils python-pygments python-pil gsfonts inkscape icoutils graphviz hunspell imagemagick
python -m pip install aafigure

44
.github/workflows/python.yml vendored Normal file
View File

@ -0,0 +1,44 @@
name: Python bindings
on: [push, pull_request]
jobs:
build:
name: build
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-20.04, macos-latest]
steps:
- uses: actions/checkout@v2
with:
submodules: recursive
- name: dependencies (macos)
if: runner.os == 'macOS'
run: |
brew install boost-build boost boost-python3 python@3.9
- name: update package lists
if: runner.os == 'Linux'
run: |
sudo apt update
- name: dependencies (linux)
if: runner.os == 'Linux'
run: |
sudo apt install libboost-tools-dev libboost-python-dev libboost-dev libboost-system-dev python3 python3-setuptools
- name: build/install
run: |
cd bindings/python
# Homebrew's python "framework" sets a prefix via distutils config.
# --prefix conflicts with --user, so null out prefix so we have one
# command that works everywhere
python3 setup.py build_ext -j3 --libtorrent-link=static install --user --prefix=
- name: tests
run: |
cd bindings/python
python3 test.py

View File

@ -632,6 +632,38 @@ if (APPLE)
target_link_libraries(torrent-rasterbar PRIVATE "-framework CoreFoundation" "-framework SystemConfiguration")
endif()
# check if we need to link with libatomic (not needed on MSVC)
if (NOT Windows)
# TODO: migrate to CheckSourceCompiles in CMake >= 3.19
include(CheckCXXSourceCompiles)
set(ATOMICS_TEST_SOURCE [=[
#include <atomic>
#include <cstdint>
std::atomic<int> x{0};
int main() {
x.fetch_add(1, std::memory_order_relaxed);
return 0;
}
]=])
string(REPLACE "std::atomic<int>" "std::atomic<std::int64_t>" ATOMICS64_TEST_SOURCE "${ATOMICS_TEST_SOURCE}")
check_cxx_source_compiles("${ATOMICS_TEST_SOURCE}" HAVE_CXX_ATOMICS_WITHOUT_LIB)
check_cxx_source_compiles("${ATOMICS64_TEST_SOURCE}" HAVE_CXX_ATOMICS64_WITHOUT_LIB)
if((NOT HAVE_CXX_ATOMICS_WITHOUT_LIB) OR (NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB))
set(CMAKE_REQUIRED_LIBRARIES "atomic")
check_cxx_source_compiles("${ATOMICS_TEST_SOURCE}" HAVE_CXX_ATOMICS_WITH_LIB)
check_cxx_source_compiles("${ATOMICS64_TEST_SOURCE}" HAVE_CXX_ATOMICS64_WITH_LIB)
if ((NOT HAVE_CXX_ATOMICS_WITH_LIB) OR (NOT HAVE_CXX_ATOMICS64_WITH_LIB))
message(FATAL_ERROR "No native support for std::atomic, or libatomic not found!")
else()
message(STATUS "Linking with libatomic for atomics support")
unset(CMAKE_REQUIRED_LIBRARIES)
target_link_libraries(torrent-rasterbar PUBLIC atomic)
endif()
endif()
endif()
feature_option(build_tests "build tests" OFF)
feature_option(build_examples "build examples" OFF)
feature_option(build_tools "build tools" OFF)

View File

@ -10,7 +10,6 @@ use-project /torrent : ../.. ;
BOOST_ROOT = [ modules.peek : BOOST_ROOT ] ;
# this is used to make bjam use the same version of python which is executing setup.py
LIBTORRENT_PYTHON_INTERPRETER = [ modules.peek : LIBTORRENT_PYTHON_INTERPRETER ] ;
feature libtorrent-link : shared static : composite propagated ;
feature libtorrent-python-pic : off on : composite propagated link-incompatible ;
@ -24,15 +23,6 @@ feature python-install-path : : free path ;
# the python module in the system directory or user-specifc directory
feature python-install-scope : user system : ;
# this is just to force boost build to pick the desired python target when using LIBTORRENT_PYTHON_INTERPRETER
feature libtorrent-python : on ;
if $(LIBTORRENT_PYTHON_INTERPRETER)
{
echo "using python interpreter at: " $(LIBTORRENT_PYTHON_INTERPRETER) ;
using python : : "$(LIBTORRENT_PYTHON_INTERPRETER)" : : : <libtorrent-python>on ;
}
# copied from boost 1.63's boost python jamfile
rule find-py3-version
{

View File

@ -1,121 +1,216 @@
#!/usr/bin/env python3
from distutils.core import setup, Extension
import distutils.debug
import os
import pathlib
import platform
import sys
import shutil
import multiprocessing
import glob
import sysconfig
import tempfile
import setuptools
import setuptools.command.build_ext as _build_ext_lib
def bjam_build():
toolset = ''
file_ext = '.so'
if platform.system() == 'Windows':
file_ext = '.pyd'
# See https://wiki.python.org/moin/WindowsCompilers for a table of msvc versions
# used for each python version
# Specify the full version number for 9.0 and 10.0 because apparently
# older versions of boost don't support only specifying the major number and
# there was only one version of msvc with those majors.
# Only specify the major for msvc-14 so that 14.1, 14.11, etc can be used.
# Hopefully people building with msvc-14 are using a new enough version of boost
# for this to work.
if sys.version_info[0:2] in ((2, 6), (2, 7), (3, 0), (3, 1), (3, 2)):
toolset = ' toolset=msvc-9.0'
elif sys.version_info[0:2] in ((3, 3), (3, 4)):
toolset = ' toolset=msvc-10.0'
elif sys.version_info[0:2] in ((3, 5), (3, 6)):
toolset = ' toolset=msvc-14.1' # libtorrent requires VS 2017 or newer
else:
# unknown python version, lets hope the user has the right version of msvc configured
toolset = ' toolset=msvc'
# on windows, just link all the dependencies together to keep it simple
toolset += ' libtorrent-link=static boost-link=static'
parallel_builds = ' -j%d' % multiprocessing.cpu_count()
if sys.maxsize > 2**32:
address_model = ' address-model=64'
else:
address_model = ' address-model=32'
# add extra quoting around the path to prevent bjam from parsing it as a list
# if the path has spaces
os.environ['LIBTORRENT_PYTHON_INTERPRETER'] = '"' + sys.executable + '"'
# build libtorrent using bjam and build the installer with distutils
cmdline = ('b2 release optimization=space stage_module --hash' +
address_model + toolset + parallel_builds)
print(cmdline)
if os.system(cmdline) != 0:
print('build failed')
sys.exit(1)
try:
os.mkdir('build')
except FileExistsError:
pass
try:
shutil.rmtree('build/lib')
except FileNotFoundError:
pass
try:
os.mkdir('build/lib')
except FileExistsError:
pass
try:
os.mkdir('libtorrent')
except FileExistsError:
pass
for f in glob.glob('libtorrent*.' + file_ext):
shutil.copyfile(f, 'build/lib/libtorrent' + file_ext)
return None
def get_msvc_toolset():
# Reference: https://wiki.python.org/moin/WindowsCompilers
major_minor = sys.version_info()[0:2]
if major_minor in ((2, 6), (2, 7), (3, 0), (3, 1), (3, 2)):
return "msvc-9.0"
if major_minor in ((3, 3), (3, 4)):
return "msvc-10.0"
if major_minor in ((3, 5), (3, 6)):
return "msvc-14.1" # libtorrent requires VS 2017 or newer
# unknown python version
return "msvc"
def distutils_build():
def b2_bool(value):
if value:
return "on"
return "off"
src_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), "src"))
source_list = [os.path.join(src_dir, s) for s in os.listdir(src_dir) if s.endswith(".cpp")]
ext = [Extension(
'libtorrent',
sources=sorted(source_list),
language='c++',
include_dirs=['../../include'],
library_dirs=[],
libraries=['torrent-rasterbar'],
extra_compile_args=['-DTORRENT_USE_OPENSSL', '-DTORRENT_USE_LIBCRYPTO',
'-DBOOST_ASIO_HAS_STD_CHRONO=1 -DBOOST_EXCEPTION_DISABLE',
'-DBOOST_ASIO_ENABLE_CANCELIO', '-DTORRENT_LINKING_SHARED',
'-DTORRENT_BUILDING_LIBRARY']
# Frustratingly, the "bdist_*" unconditionally (re-)run "build" without
# args, even ignoring "build_*" earlier on the same command line. This
# means "build_*" must be a no-op if some build output exists, even if that
# output might have been generated with different args (like
# "--define=FOO"). b2 does not know how to be "naively idempotent" like
# this; it will only generate outputs that exactly match the build request.
#
# It doesn't work to short-circuit initialize_options() / finalize_options(),
# as this doesn't play well with the way options are externally manipulated by
# distutils.
#
# It DOES work to short-circuit Distribution.reinitialize_command(), so we do
# that here.
class B2Distribution(setuptools.Distribution):
def reinitialize_command(self, command, reinit_subcommands=0):
if command == "build_ext":
return self.get_command_obj("build_ext")
return super().reinitialize_command(
command, reinit_subcommands=reinit_subcommands
)
# Various setuptools logic expects us to provide Extension instances for each
# extension in the distro.
class StubExtension(setuptools.Extension):
def __init__(self, name):
# An empty sources list ensures the base build_ext command won't build
# anything
super().__init__(name, sources=[])
def write_b2_python_config(config):
write = config.write
# b2 normally keys python environments by X.Y version, but since we may
# have a duplicates, we also key on a special property. It's always-on, so
# any python versions configured with this as a condition will always be
# picked.
# Note that python.jam actually modifies the condition for the build
# request, so that <define>TORRENT_FOO becomes something like
# <define>TORRENT_FOO,<python>3.7,<target-os>linux:... which causes chaos.
# We should always define a custom feature for the condition.
write("import feature ;\n")
write("feature.feature libtorrent-python : on ;\n")
# python.jam tries to determine correct include and library paths. Per
# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=691378 , include
# detection is broken, but debian's fix is also broken (invokes a global
# pythonX.Y instead of the passed interpreter)
paths = sysconfig.get_paths()
includes = [paths["include"], paths["platinclude"]]
write("using python")
write(f" : {sysconfig.get_python_version()}")
write(f' : "{sys.executable}"')
write(" : ")
write(" ".join(f'"{path}"' for path in includes))
write(" :") # libraries
write(" : <libtorrent-python>on")
# Note that on debian, the extension suffix is overwritten, but it's
# necessary everywhere else, or else b2 will just build "libtorrent.so".
# python.jam appends SHLIB_SUFFIX on its own.
ext_suffix = sysconfig.get_config_var("EXT_SUFFIX")
shlib_suffix = sysconfig.get_config_var("SHLIB_SUFFIX")
ext_suffix = ext_suffix[: -len(shlib_suffix)]
write(f' : "{ext_suffix}"')
write(" ;\n")
BuildExtBase = _build_ext_lib.build_ext
class LibtorrentBuildExt(BuildExtBase):
user_options = BuildExtBase.user_options + [
(
"libtorrent-link=",
None,
"how to link to libtorrent ('static' or 'shared')",
),
(
"boost-link=",
None,
"how to link to boost-python ('static' or 'shared')",
),
("toolset=", None, "b2 toolset"),
("pic", None, "whether to compile with -fPIC"),
("optimization=", None, "b2 optimization mode"),
(
"hash",
None,
"use a property hash for the build directory, rather than "
"property subdirectories",
),
("cxxstd=", None, "boost cxxstd value (14, 17, 20, etc.)"),
]
return ext
boolean_options = BuildExtBase.boolean_options + ["pic", "hash"]
def initialize_options(self):
self.libtorrent_link = None
self.boost_link = None
self.toolset = None
self.pic = None
self.optimization = None
self.hash = None
self.cxxstd = None
return super().initialize_options()
def run(self):
# The current jamfile layout just supports one extension
self.build_extension_with_b2()
return super().run()
def build_extension_with_b2(self):
if os.name == "nt":
self.toolset = get_msvc_toolset()
self.libtorrent_link = "static"
self.boost_link = "static"
args = []
if distutils.debug.DEBUG:
args.append("--debug-configuration")
args.append("--debug-building")
args.append("--debug-generators")
variant = "debug" if self.debug else "release"
args.append(variant)
bits = 64 if sys.maxsize > 2 ** 32 else 32
args.append(f"address-model={bits}")
if self.parallel:
args.append(f"-j{self.parallel}")
if self.libtorrent_link:
args.append(f"libtorrent-link={self.libtorrent_link}")
if self.boost_link:
args.append(f"boost-link={self.boost_link}")
if self.pic:
args.append(f"libtorrent-python-pic={b2_bool(self.pic)}")
if self.optimization:
args.append(f"optimization={self.optimization}")
if self.hash:
args.append("--hash")
if self.cxxstd:
args.append(f"cxxstd={self.cxxstd}")
# Jamfile hack to copy the module to our target directory
target = pathlib.Path(self.get_ext_fullpath("libtorrent"))
args.append(f"python-install-path={target.parent}")
args.append("install_module")
# We use a "project-config.jam" to instantiate a python environment
# to exactly match the running one.
config = tempfile.NamedTemporaryFile(mode="w+", delete=False)
try:
write_b2_python_config(config)
config.seek(0)
self.announce("project-config.jam contents:")
self.announce(config.read())
config.close()
args.append(f"--project-config={config.name}")
self.spawn(["b2"] + args)
finally:
os.unlink(config.name)
ext = None
if '--help' not in sys.argv \
and '--help-commands' not in sys.argv:
ext = bjam_build()
# ext = distutils_build()
setup(
name='python-libtorrent',
version='2.0.1',
author='Arvid Norberg',
author_email='arvid@libtorrent.org',
description='Python bindings for libtorrent-rasterbar',
long_description='Python bindings for libtorrent-rasterbar',
url='http://libtorrent.org',
platforms=[platform.system() + '-' + platform.machine()],
license='BSD',
packages=['libtorrent'],
ext_modules=ext
setuptools.setup(
name="python-libtorrent",
version="2.0.1",
author="Arvid Norberg",
author_email="arvid@libtorrent.org",
description="Python bindings for libtorrent-rasterbar",
long_description="Python bindings for libtorrent-rasterbar",
url="http://libtorrent.org",
license="BSD",
ext_modules=[StubExtension("libtorrent")],
cmdclass={
"build_ext": LibtorrentBuildExt,
},
distclass=B2Distribution,
)

View File

@ -90,7 +90,7 @@ struct dht_server
return;
}
std::printf("%s: DHT initialized on port %d\n", time_now_string(), m_port);
std::printf("%s: DHT initialized on port %d\n", time_now_string().c_str(), m_port);
m_thread = std::make_shared<std::thread>(&dht_server::thread_fun, this);
}

View File

@ -89,7 +89,7 @@ struct peer_server
return;
}
std::printf("%s: PEER peer initialized on port %d\n", time_now_string(), m_port);
std::printf("%s: PEER peer initialized on port %d\n", time_now_string().c_str(), m_port);
m_thread = std::make_shared<std::thread>(&peer_server::thread_fun, this);
}
@ -137,7 +137,7 @@ struct peer_server
return;
}
std::printf("%s: PEER incoming peer connection\n", time_now_string());
std::printf("%s: PEER incoming peer connection\n", time_now_string().c_str());
++m_peer_requests;
socket.close(ec);
}

View File

@ -309,7 +309,7 @@ alert const* wait_for_alert(lt::session& ses, int type, char const* name
auto a = *i;
if (should_print(a))
{
std::printf("%s: %s: [%s] %s\n", time_now_string(), name
std::printf("%s: %s: [%s] %s\n", time_now_string().c_str(), name
, a->what(), a->message().c_str());
}
if (a->type() == type)
@ -397,7 +397,7 @@ bool print_alerts(lt::session& ses, char const* name
{
if (peer_disconnected_alert const* p = alert_cast<peer_disconnected_alert>(a))
{
std::printf("%s: %s: [%s] (%s): %s\n", time_to_string(a->timestamp())
std::printf("%s: %s: [%s] (%s): %s\n", time_to_string(a->timestamp()).c_str()
, name, a->what()
, print_endpoint(p->endpoint).c_str(), p->message().c_str());
}
@ -413,7 +413,7 @@ bool print_alerts(lt::session& ses, char const* name
}
else if (should_print(a) && !no_output)
{
std::printf("%s: %s: [%s] %s\n", time_now_string(), name, a->what(), a->message().c_str());
std::printf("%s: %s: [%s] %s\n", time_now_string().c_str(), name, a->what(), a->message().c_str());
}
TEST_CHECK(alert_cast<fastresume_rejected_alert>(a) == nullptr || allow_failed_fastresume);
@ -778,13 +778,13 @@ int start_proxy(int proxy_type)
char buf[1024];
std::snprintf(buf, sizeof(buf), "%s %s --port %d%s", python_exe.c_str(), cmd, port, auth);
std::printf("%s starting proxy on port %d (%s %s)...\n", time_now_string(), port, type, auth);
std::printf("%s starting proxy on port %d (%s %s)...\n", time_now_string().c_str(), port, type, auth);
std::printf("%s\n", buf);
pid_type r = async_run(buf);
if (r == 0) continue;
proxy_t t = { r, proxy_type };
running_proxies.insert(std::make_pair(port, t));
std::printf("%s launched\n", time_now_string());
std::printf("%s launched\n", time_now_string().c_str());
std::this_thread::sleep_for(lt::milliseconds(500));
wait_for_port(port);
return port;
@ -1112,17 +1112,17 @@ setup_transfer(lt::session* ses1, lt::session* ses2, lt::session* ses3
if (use_ssl_ports)
{
port = ses2->ssl_listen_port();
std::printf("%s: ses2->ssl_listen_port(): %d\n", time_now_string(), port);
std::printf("%s: ses2->ssl_listen_port(): %d\n", time_now_string().c_str(), port);
}
if (port == 0)
{
port = ses2->listen_port();
std::printf("%s: ses2->listen_port(): %d\n", time_now_string(), port);
std::printf("%s: ses2->listen_port(): %d\n", time_now_string().c_str(), port);
}
std::printf("%s: ses1: connecting peer port: %d\n"
, time_now_string(), port);
, time_now_string().c_str(), port);
tor1.connect_peer(tcp::endpoint(make_address("127.0.0.1", ec)
, std::uint16_t(port)));
@ -1185,13 +1185,13 @@ int start_web_server(bool ssl, bool chunked_encoding, bool keepalive, int min_in
std::snprintf(buf, sizeof(buf), "%s .." SEPARATOR "web_server.py %d %d %d %d %d"
, python_exe.c_str(), port, chunked_encoding, ssl, keepalive, min_interval);
std::printf("%s starting web_server on port %d...\n", time_now_string(), port);
std::printf("%s starting web_server on port %d...\n", time_now_string().c_str(), port);
std::printf("%s\n", buf);
pid_type r = async_run(buf);
if (r == 0) continue;
web_server_pid = r;
std::printf("%s launched\n", time_now_string());
std::printf("%s launched\n", time_now_string().c_str());
std::this_thread::sleep_for(lt::milliseconds(1000));
wait_for_port(port);
return port;

View File

@ -80,7 +80,7 @@ void log(char const* fmt, ...)
va_end(v);
std::printf("\x1b[1m\x1b[36m%s: %s\x1b[0m\n"
, time_now_string(), buf);
, time_now_string().c_str(), buf);
}
void print_session_log(lt::session& ses)

View File

@ -236,7 +236,7 @@ session_proxy test_proxy(settings_pack::proxy_type_t proxy_type, flags_t flags)
, udp_tracker_url) == accepted_trackers.end());
}
std::printf("%s: ~session\n", time_now_string());
std::printf("%s: ~session\n", time_now_string().c_str());
session_proxy pr = s->abort();
s.reset();

View File

@ -136,7 +136,7 @@ void test_ssl(int const test_idx, bool const use_utp)
test_config_t const& test = test_config[test_idx];
std::printf("\n%s TEST: %s Protocol: %s\n\n", time_now_string()
std::printf("\n%s TEST: %s Protocol: %s\n\n", time_now_string().c_str()
, test.name, use_utp ? "uTP": "TCP");
// in case the previous run was terminated
@ -234,7 +234,7 @@ void test_ssl(int const test_idx, bool const use_utp)
// connect the peers after setting the certificates
if (test.use_ssl_ports == false) port += 20;
std::printf("\n\n%s: ses1: connecting peer port: %d\n\n\n"
, time_now_string(), port);
, time_now_string().c_str(), port);
tor1.connect_peer(tcp::endpoint(make_address("127.0.0.1", ec)
, std::uint16_t(port)));
@ -297,9 +297,9 @@ void test_ssl(int const test_idx, bool const use_utp)
TEST_EQUAL(peer_errors > 0, test.peer_errors > 0);
}
char const* now = time_now_string();
std::printf("%s: EXPECT: %s\n", now, test.expected_to_complete ? "SUCCEESS" : "FAILURE");
std::printf("%s: RESULT: %s\n", now, tor2.status().is_seeding ? "SUCCEESS" : "FAILURE");
std::string const now = time_now_string();
std::printf("%s: EXPECT: %s\n", now.c_str(), test.expected_to_complete ? "SUCCEESS" : "FAILURE");
std::printf("%s: RESULT: %s\n", now.c_str(), tor2.status().is_seeding ? "SUCCEESS" : "FAILURE");
TEST_EQUAL(tor2.status().is_seeding, test.expected_to_complete);
// this allows shutting down the sessions in parallel

View File

@ -133,7 +133,7 @@ void on_piece_checked(piece_index_t, sha1_hash const&
void print_error(char const* call, int ret, storage_error const& ec)
{
std::printf("%s: %s() returned: %d error: \"%s\" in file: %d operation: %s\n"
, time_now_string(), call, ret, ec.ec.message().c_str()
, time_now_string().c_str(), call, ret, ec.ec.message().c_str()
, static_cast<int>(ec.file()), operation_name(ec.operation));
}

View File

@ -42,15 +42,15 @@ POSSIBILITY OF SUCH DAMAGE.
namespace libtorrent
{
char const* time_now_string()
std::string time_now_string()
{
return time_to_string(clock_type::now());
}
char const* time_to_string(time_point const tp)
std::string time_to_string(time_point const tp)
{
static const time_point start = clock_type::now();
static char ret[200];
char ret[200];
int t = int(total_milliseconds(tp - start));
int h = t / 1000 / 60 / 60;
t -= h * 60 * 60 * 1000;

View File

@ -33,6 +33,8 @@ POSSIBILITY OF SUCH DAMAGE.
#ifndef TEST_UTILS_HPP
#define TEST_UTILS_HPP
#include <string>
#include "test.hpp"
#include "libtorrent/time.hpp"
#include "libtorrent/download_priority.hpp"
@ -45,8 +47,8 @@ POSSIBILITY OF SUCH DAMAGE.
namespace libtorrent
{
EXPORT char const* time_now_string();
EXPORT char const* time_to_string(lt::time_point const tp);
EXPORT std::string time_now_string();
EXPORT std::string time_to_string(lt::time_point const tp);
}
inline lt::download_priority_t operator "" _pri(unsigned long long const p)

View File

@ -69,13 +69,13 @@ struct udp_tracker
{
if (ec)
{
std::printf("%s: UDP tracker, read failed: %s\n", time_now_string(), ec.message().c_str());
std::printf("%s: UDP tracker, read failed: %s\n", time_now_string().c_str(), ec.message().c_str());
return;
}
if (bytes_transferred < 16)
{
std::printf("%s: UDP message too short (from: %s)\n", time_now_string(), print_endpoint(*from).c_str());
std::printf("%s: UDP message too short (from: %s)\n", time_now_string().c_str(), print_endpoint(*from).c_str());
return;
}
@ -84,7 +84,7 @@ struct udp_tracker
return;
}
std::printf("%s: UDP message %d bytes\n", time_now_string(), int(bytes_transferred));
std::printf("%s: UDP message %d bytes\n", time_now_string().c_str(), int(bytes_transferred));
char* ptr = buffer;
aux::read_uint64(ptr);
@ -103,7 +103,7 @@ struct udp_tracker
, int(bytes_transferred));
return;
}
std::printf("%s: UDP connect from %s\n", time_now_string()
std::printf("%s: UDP connect from %s\n", time_now_string().c_str()
, print_endpoint(*from).c_str());
ptr = buffer;
aux::write_uint32(0, ptr); // action = connect
@ -111,9 +111,9 @@ struct udp_tracker
aux::write_uint64(10, ptr); // connection_id
m_socket.send_to(boost::asio::buffer(buffer, 16), *from, 0, e);
if (e) std::printf("%s: UDP send_to failed. ERROR: %s\n"
, time_now_string(), e.message().c_str());
, time_now_string().c_str(), e.message().c_str());
else std::printf("%s: UDP sent response to: %s\n"
, time_now_string(), print_endpoint(*from).c_str());
, time_now_string().c_str(), print_endpoint(*from).c_str());
break;
case 1: // announce
@ -126,7 +126,7 @@ struct udp_tracker
}
++m_udp_announces;
std::printf("%s: UDP announce [%d]\n", time_now_string()
std::printf("%s: UDP announce [%d]\n", time_now_string().c_str()
, int(m_udp_announces));
ptr = buffer;
aux::write_uint32(1, ptr); // action = announce
@ -157,16 +157,16 @@ struct udp_tracker
m_socket.send_to(boost::asio::buffer(buffer
, static_cast<std::size_t>(ptr - buffer)), *from, 0, e);
if (e) std::printf("%s: UDP send_to failed. ERROR: %s\n"
, time_now_string(), e.message().c_str());
, time_now_string().c_str(), e.message().c_str());
else std::printf("%s: UDP sent response to: %s\n"
, time_now_string(), print_endpoint(*from).c_str());
, time_now_string().c_str(), print_endpoint(*from).c_str());
break;
case 2:
// ignore scrapes
std::printf("%s: UDP scrape (ignored)\n", time_now_string());
std::printf("%s: UDP scrape (ignored)\n", time_now_string().c_str());
break;
default:
std::printf("%s: UDP unknown message: %d\n", time_now_string()
std::printf("%s: UDP unknown message: %d\n", time_now_string().c_str()
, action);
break;
}
@ -200,14 +200,14 @@ struct udp_tracker
}
std::printf("%s: UDP tracker [%p] initialized on port %d\n"
, time_now_string(), static_cast<void*>(this), m_port);
, time_now_string().c_str(), static_cast<void*>(this), m_port);
m_thread = std::make_shared<std::thread>(&udp_tracker::thread_fun, this);
}
void stop()
{
std::printf("%s: UDP tracker [%p], stop\n", time_now_string()
std::printf("%s: UDP tracker [%p], stop\n", time_now_string().c_str()
, static_cast<void*>(this));
m_abort = true;
m_socket.cancel();
@ -217,7 +217,7 @@ struct udp_tracker
~udp_tracker()
{
std::printf("%s: UDP tracker [%p], ~udp_tracker\n"
, time_now_string(), static_cast<void*>(this));
, time_now_string().c_str(), static_cast<void*>(this));
post(m_ios, std::bind(&udp_tracker::stop, this));
if (m_thread) m_thread->join();
}

View File

@ -59,9 +59,9 @@ def substitute_file(name):
elif 'VERSION=' in line and name.endswith('Makefile'):
line = 'VERSION=%d.%d.%d\n' % (version[0], version[1], version[2])
elif 'version=' in line and name.endswith('setup.py'):
line = " version='%d.%d.%d',\n" % (version[0], version[1], version[2])
line = " version=\"%d.%d.%d\",\n" % (version[0], version[1], version[2])
elif "version = '" in line and name.endswith('setup.py'):
line = " version='%d.%d.%d',\n" % (version[0], version[1], version[2])
line = " version=\"%d.%d.%d\",\n" % (version[0], version[1], version[2])
elif '"-LT' in line and name.endswith('settings_pack.cpp'):
line = re.sub('"-LT[0-9A-Za-z]{4}-"', '"-LT%c%c%c%c-"' % v(version), line)