Hello community, here is the log from the commit of package libfilezilla for openSUSE:Factory checked in at 2016-08-05 18:18:14 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libfilezilla (Old) and /work/SRC/openSUSE:Factory/.libfilezilla.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libfilezilla" Changes: -------- --- /work/SRC/openSUSE:Factory/libfilezilla/libfilezilla.changes 2016-07-12 23:51:04.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.libfilezilla.new/libfilezilla.changes 2016-08-05 18:18:15.000000000 +0200 @@ -1,0 +2,12 @@ +Fri Jul 29 15:45:32 UTC 2016 - [email protected] + +- update to 0.6.1 + * Bugfixes and minor changes: + - Fix UTF-8 conversion functions and added a testcase + +- update to 0.6.0 + * New features: + - Add fz::sprintf, a safe replacement for for the C sprintf + function + +------------------------------------------------------------------- Old: ---- libfilezilla-0.5.3.tar.bz2 New: ---- libfilezilla-0.6.1.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libfilezilla.spec ++++++ --- /var/tmp/diff_new_pack.svdjc5/_old 2016-08-05 18:18:16.000000000 +0200 +++ /var/tmp/diff_new_pack.svdjc5/_new 2016-08-05 18:18:16.000000000 +0200 @@ -20,7 +20,7 @@ %define libname %{name}%{major} %define develname %{name}-devel Name: libfilezilla -Version: 0.5.3 +Version: 0.6.1 Release: 0 Summary: C++ library for filezilla License: GPL-2.0+ ++++++ libfilezilla-0.5.3.tar.bz2 -> libfilezilla-0.6.1.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libfilezilla-0.5.3/NEWS new/libfilezilla-0.6.1/NEWS --- old/libfilezilla-0.5.3/NEWS 2016-06-20 10:11:27.000000000 +0200 +++ new/libfilezilla-0.6.1/NEWS 2016-07-27 14:07:50.000000000 +0200 @@ -1,6 +1,14 @@ +0.6.1 (2016-07-27) + +- Fix UTF-8 conversion functions and added a testcase + +0.6.0 (2016-07-20) + ++ Add fz::sprintf, a safe replacement for for the C sprintf function + 0.5.3 (2016-06-20) -+ Add fz::replace_substrincs to search and replace substrings in std::(w)string ++ Add fz::replace_substrings to search and replace substrings in std::(w)string - Explicitly request large file support on 32bit systems 0.5.2 (2016-05-20) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libfilezilla-0.5.3/configure new/libfilezilla-0.6.1/configure --- old/libfilezilla-0.5.3/configure 2016-06-20 10:12:34.000000000 +0200 +++ new/libfilezilla-0.6.1/configure 2016-07-27 14:08:39.000000000 +0200 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for libfilezilla 0.5.3. +# Generated by GNU Autoconf 2.69 for libfilezilla 0.6.1. # # Report bugs to <[email protected]>. # @@ -590,8 +590,8 @@ # Identity of this package. PACKAGE_NAME='libfilezilla' PACKAGE_TARNAME='libfilezilla' -PACKAGE_VERSION='0.5.3' -PACKAGE_STRING='libfilezilla 0.5.3' +PACKAGE_VERSION='0.6.1' +PACKAGE_STRING='libfilezilla 0.6.1' PACKAGE_BUGREPORT='[email protected]' PACKAGE_URL='https://lib.filezilla-project.org/' @@ -1396,7 +1396,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures libfilezilla 0.5.3 to adapt to many kinds of systems. +\`configure' configures libfilezilla 0.6.1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1466,7 +1466,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of libfilezilla 0.5.3:";; + short | recursive ) echo "Configuration of libfilezilla 0.6.1:";; esac cat <<\_ACEOF @@ -1591,7 +1591,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -libfilezilla configure 0.5.3 +libfilezilla configure 0.6.1 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2036,7 +2036,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by libfilezilla $as_me 0.5.3, which was +It was created by libfilezilla $as_me 0.6.1, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2902,7 +2902,7 @@ # Define the identity of the package. PACKAGE='libfilezilla' - VERSION='0.5.3' + VERSION='0.6.1' cat >>confdefs.h <<_ACEOF @@ -19665,7 +19665,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by libfilezilla $as_me 0.5.3, which was +This file was extended by libfilezilla $as_me 0.6.1, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -19732,7 +19732,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -libfilezilla config.status 0.5.3 +libfilezilla config.status 0.6.1 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libfilezilla-0.5.3/configure.ac new/libfilezilla-0.6.1/configure.ac --- old/libfilezilla-0.5.3/configure.ac 2016-06-20 10:09:42.000000000 +0200 +++ new/libfilezilla-0.6.1/configure.ac 2016-07-27 14:04:28.000000000 +0200 @@ -1,4 +1,4 @@ -AC_INIT([libfilezilla],[0.5.3],[[email protected]],[],[https://lib.filezilla-project.org/]) +AC_INIT([libfilezilla],[0.6.1],[[email protected]],[],[https://lib.filezilla-project.org/]) AC_CONFIG_HEADERS([lib/libfilezilla/private/config.hpp]) AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_AUX_DIR(config) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libfilezilla-0.5.3/demos/demo_events.vcxproj new/libfilezilla-0.6.1/demos/demo_events.vcxproj --- old/libfilezilla-0.5.3/demos/demo_events.vcxproj 2015-11-19 14:20:07.000000000 +0100 +++ new/libfilezilla-0.6.1/demos/demo_events.vcxproj 2016-07-20 10:41:55.000000000 +0200 @@ -249,7 +249,7 @@ <Optimization>MaxSpeed</Optimization> <FunctionLevelLinking>true</FunctionLevelLinking> <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>FZ_USING_DLL;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> <MultiProcessorCompilation>true</MultiProcessorCompilation> </ClCompile> <Link> @@ -268,6 +268,7 @@ <Optimization>MaxSpeed</Optimization> <FunctionLevelLinking>true</FunctionLevelLinking> <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> <MultiProcessorCompilation>true</MultiProcessorCompilation> </ClCompile> <Link> @@ -286,7 +287,7 @@ <Optimization>MaxSpeed</Optimization> <FunctionLevelLinking>true</FunctionLevelLinking> <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>FZ_USING_DLL;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> <MultiProcessorCompilation>true</MultiProcessorCompilation> </ClCompile> <Link> @@ -305,6 +306,7 @@ <Optimization>MaxSpeed</Optimization> <FunctionLevelLinking>true</FunctionLevelLinking> <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> <MultiProcessorCompilation>true</MultiProcessorCompilation> </ClCompile> <Link> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libfilezilla-0.5.3/demos/demo_process.vcxproj new/libfilezilla-0.6.1/demos/demo_process.vcxproj --- old/libfilezilla-0.5.3/demos/demo_process.vcxproj 2015-11-19 14:20:07.000000000 +0100 +++ new/libfilezilla-0.6.1/demos/demo_process.vcxproj 2016-07-20 10:41:55.000000000 +0200 @@ -249,7 +249,7 @@ <Optimization>MaxSpeed</Optimization> <FunctionLevelLinking>true</FunctionLevelLinking> <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>FZ_USING_DLL;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> <MultiProcessorCompilation>true</MultiProcessorCompilation> </ClCompile> <Link> @@ -268,6 +268,7 @@ <Optimization>MaxSpeed</Optimization> <FunctionLevelLinking>true</FunctionLevelLinking> <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> <MultiProcessorCompilation>true</MultiProcessorCompilation> </ClCompile> <Link> @@ -286,7 +287,7 @@ <Optimization>MaxSpeed</Optimization> <FunctionLevelLinking>true</FunctionLevelLinking> <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>FZ_USING_DLL;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> <MultiProcessorCompilation>true</MultiProcessorCompilation> </ClCompile> <Link> @@ -305,6 +306,7 @@ <Optimization>MaxSpeed</Optimization> <FunctionLevelLinking>true</FunctionLevelLinking> <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> <MultiProcessorCompilation>true</MultiProcessorCompilation> </ClCompile> <Link> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libfilezilla-0.5.3/demos/demo_timer_fizzbuzz.vcxproj new/libfilezilla-0.6.1/demos/demo_timer_fizzbuzz.vcxproj --- old/libfilezilla-0.5.3/demos/demo_timer_fizzbuzz.vcxproj 2015-11-19 14:20:07.000000000 +0100 +++ new/libfilezilla-0.6.1/demos/demo_timer_fizzbuzz.vcxproj 2016-07-20 10:41:55.000000000 +0200 @@ -257,7 +257,7 @@ <Optimization>MaxSpeed</Optimization> <FunctionLevelLinking>true</FunctionLevelLinking> <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>FZ_USING_DLL;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> <MultiProcessorCompilation>true</MultiProcessorCompilation> </ClCompile> <Link> @@ -276,6 +276,7 @@ <Optimization>MaxSpeed</Optimization> <FunctionLevelLinking>true</FunctionLevelLinking> <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> <MultiProcessorCompilation>true</MultiProcessorCompilation> </ClCompile> <Link> @@ -294,7 +295,7 @@ <Optimization>MaxSpeed</Optimization> <FunctionLevelLinking>true</FunctionLevelLinking> <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>FZ_USING_DLL;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> <MultiProcessorCompilation>true</MultiProcessorCompilation> </ClCompile> <Link> @@ -313,6 +314,7 @@ <Optimization>MaxSpeed</Optimization> <FunctionLevelLinking>true</FunctionLevelLinking> <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> <MultiProcessorCompilation>true</MultiProcessorCompilation> </ClCompile> <Link> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libfilezilla-0.5.3/lib/Makefile.am new/libfilezilla-0.6.1/lib/Makefile.am --- old/libfilezilla-0.5.3/lib/Makefile.am 2016-02-21 11:35:46.000000000 +0100 +++ new/libfilezilla-0.6.1/lib/Makefile.am 2016-07-05 09:30:27.000000000 +0200 @@ -22,6 +22,7 @@ libfilezilla/event_handler.hpp \ libfilezilla/event_loop.hpp \ libfilezilla/file.hpp \ + libfilezilla/format.hpp \ libfilezilla/iputils.hpp \ libfilezilla/libfilezilla.hpp \ libfilezilla/local_filesys.hpp \ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libfilezilla-0.5.3/lib/Makefile.in new/libfilezilla-0.6.1/lib/Makefile.in --- old/libfilezilla-0.5.3/lib/Makefile.in 2016-06-20 10:12:34.000000000 +0200 +++ new/libfilezilla-0.6.1/lib/Makefile.in 2016-07-27 14:08:39.000000000 +0200 @@ -393,6 +393,7 @@ libfilezilla/event_handler.hpp \ libfilezilla/event_loop.hpp \ libfilezilla/file.hpp \ + libfilezilla/format.hpp \ libfilezilla/iputils.hpp \ libfilezilla/libfilezilla.hpp \ libfilezilla/local_filesys.hpp \ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libfilezilla-0.5.3/lib/iputils.cpp new/libfilezilla-0.6.1/lib/iputils.cpp --- old/libfilezilla-0.5.3/lib/iputils.cpp 2016-04-15 09:52:15.000000000 +0200 +++ new/libfilezilla-0.6.1/lib/iputils.cpp 2016-07-05 09:30:27.000000000 +0200 @@ -171,10 +171,10 @@ Char const dot = '.'; // IPv4 mapped String ipv4 = - convert<String>(hex_char_to_int(long_address[30]) * 16 + hex_char_to_int(long_address[31])) + dot + - convert<String>(hex_char_to_int(long_address[32]) * 16 + hex_char_to_int(long_address[33])) + dot + - convert<String>(hex_char_to_int(long_address[35]) * 16 + hex_char_to_int(long_address[36])) + dot + - convert<String>(hex_char_to_int(long_address[37]) * 16 + hex_char_to_int(long_address[38])); + toString<String>(hex_char_to_int(long_address[30]) * 16 + hex_char_to_int(long_address[31])) + dot + + toString<String>(hex_char_to_int(long_address[32]) * 16 + hex_char_to_int(long_address[33])) + dot + + toString<String>(hex_char_to_int(long_address[35]) * 16 + hex_char_to_int(long_address[36])) + dot + + toString<String>(hex_char_to_int(long_address[37]) * 16 + hex_char_to_int(long_address[38])); return do_is_routable_address(ipv4); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libfilezilla-0.5.3/lib/libfilezilla/event_handler.hpp new/libfilezilla-0.6.1/lib/libfilezilla/event_handler.hpp --- old/libfilezilla-0.5.3/lib/libfilezilla/event_handler.hpp 2015-11-02 14:47:31.000000000 +0100 +++ new/libfilezilla-0.6.1/lib/libfilezilla/event_handler.hpp 2016-07-20 10:41:55.000000000 +0200 @@ -91,6 +91,11 @@ event_loop_.send_event(this, new T(std::forward<Args>(args)...)); } + template<typename T> + void send_event(T* evt) { + event_loop_.send_event(this, evt); + } + /** \brief Adds a timer, returns the timer id. * * Once the interval expires, you get a timer event from the event loop. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libfilezilla-0.5.3/lib/libfilezilla/format.hpp new/libfilezilla-0.6.1/lib/libfilezilla/format.hpp --- old/libfilezilla-0.5.3/lib/libfilezilla/format.hpp 1970-01-01 01:00:00.000000000 +0100 +++ new/libfilezilla-0.6.1/lib/libfilezilla/format.hpp 2016-07-20 10:41:59.000000000 +0200 @@ -0,0 +1,360 @@ +#ifndef LIBFILEZILLA_FORMAT_HEADER +#define LIBFILEZILLA_FORMAT_HEADER + +#include "string.hpp" + +#include <cstdlib> + +#include <assert.h> + +/** \file +* \brief Header for the \ref fz::sprintf "sprintf" string formatting function +*/ + +namespace fz { + +/// \cond +namespace detail { + +// Get flags +enum : char { + pad_0 = 1, + pad_blank = 2, + with_width = 4 +}; + +// Converts integral type to desired string type... +// ... basic case: simple unsigned value +template<typename String, bool Unsigned, typename Arg> +typename std::enable_if_t<std::is_integral<std::decay_t<Arg>>::value && !std::is_enum<std::decay_t<Arg>>::value, String> integral_to_string(char flags, int width, Arg && arg) +{ + std::decay_t<Arg> v = arg; + + char lead{}; + + assert(!Unsigned || !std::is_signed<std::decay_t<Arg>>::value || arg >= 0); + + if (std::is_signed<std::decay_t<Arg>>::value && !(arg >= 0)) { + lead = '-'; + } + else if (flags & pad_blank && arg >= 0) { + lead = ' '; + } + + + // max decimal digits in b-bit integer is floor((b-1) * log_10(2)) + 1 < b * 0.5 + 1 + typename String::value_type buf[sizeof(v) * 4 + 1]; + auto *const end = buf + sizeof(v) * 4 + 1; + auto *p = end; + + do { + int const mod = std::abs(static_cast<int>(v % 10)); + *(--p) = '0' + mod; + v /= 10; + } while (v); + + if (flags & with_width) { + if (lead && width > 0) { + --width; + } + + String ret; + + if (flags & pad_0) { + if (lead) { + ret += lead; + } + if (end - p < width) { + ret.append(width - (end - p), '0'); + } + } + else { + if (end - p < width) { + ret.append(width - (end - p), ' '); + } + if (lead) { + ret += lead; + } + } + + ret.append(p, end); + return ret; + } + else { + if (lead) { + *(--p) = lead; + } + return String(p, end); + } +} + +// ... for strongly typed enums +template<typename String, bool Unsigned, typename Arg> +typename std::enable_if_t<std::is_enum<std::decay_t<Arg>>::value, String> integral_to_string(char flags, int width, Arg && arg) +{ + return integral_to_string<String, Unsigned>(flags, width, static_cast<std::underlying_type_t<std::decay_t<Arg>>>(arg)); +} + +// ... assert otherwise +template<typename String, bool Unsigned, typename Arg> +typename std::enable_if_t<!std::is_integral<std::decay_t<Arg>>::value && !std::is_enum<std::decay_t<Arg>>::value, String> integral_to_string(char, int, Arg &&) +{ + assert(0); + return String(); +} + + +// Converts argument to string... +// ... if toString(arg) is valid expression +template<typename String, typename Arg> +auto arg_to_string(Arg&& arg) -> decltype(toString<String>(std::forward<Arg>(arg))) +{ + return toString<String>(std::forward<Arg>(arg)); +} + +// ... assert otherwise +template<typename String> +String arg_to_string(...) +{ + assert(0); + return String(); +} + + +// Converts integral type to hex string with desired string type... +// ... basic case: simple unsigned value +template<typename String, bool Lowercase, typename Arg> +typename std::enable_if_t<std::is_integral<std::decay_t<Arg>>::value && !std::is_enum<std::decay_t<Arg>>::value, String> integral_to_hex_string(Arg && arg) +{ + std::decay_t<Arg> v = arg; + typename String::value_type buf[sizeof(v) * 2]; + auto *const end = buf + sizeof(v) * 2; + auto *p = end; + + do { + *(--p) = fz::int_to_hex_char<typename String::value_type, Lowercase>(v & 0xf); + v >>= 4; + } while (v); + + return String(p, end); +} + +// ... for enums +template<typename String, bool Lowercase, typename Arg> +typename std::enable_if_t<std::is_enum<std::decay_t<Arg>>::value, String> integral_to_hex_string(Arg && arg) +{ + return integral_to_hex_string<String, Lowercase>(static_cast<std::underlying_type_t<std::decay_t<Arg>>>(arg)); +} + +// ... assert otherwise +template<typename String, bool Lowercase, typename Arg> +typename std::enable_if_t<!std::is_integral<std::decay_t<Arg>>::value && !std::is_enum<std::decay_t<Arg>>::value, String> integral_to_hex_string(Arg &&) +{ + assert(0); + return String(); +} + + +// Converts to pointer to hex string +template<typename String, typename Arg> +typename std::enable_if_t<std::is_pointer<std::decay_t<Arg>>::value, String> pointer_to_string(Arg&& arg) +{ + return String({'0', 'x'}) + integral_to_hex_string<String, true>(reinterpret_cast<uintptr_t>(arg)); +} + + +template<typename String, typename Arg> +typename std::enable_if_t<!std::is_pointer<std::decay_t<Arg>>::value, String> pointer_to_string(Arg&& arg) +{ + assert(0); + return String(); +} + + +template<typename String, typename... Args> +String extract_arg(char, size_t, typename String::value_type, size_t) +{ + return String(); +} + +template<typename String, typename Arg, typename... Args> +String extract_arg(char flags, size_t width, typename String::value_type type, size_t arg_n, Arg&& arg, Args&&...args) +{ + String ret; + + if (!arg_n) { + if (type == 's') { + ret = arg_to_string<String>(std::forward<Arg>(arg)); + if (flags & with_width && ret.size() < width) { + ret = String(width - ret.size(), ' ') + ret; + } + } + else if (type == 'd' || type == 'i') { + ret = integral_to_string<String, false>(flags, width, std::forward<Arg>(arg)); + } + else if (type == 'u') { + ret = integral_to_string<String, true>(flags, width, std::forward<Arg>(arg)); + } + else if (type == 'x') { + ret = integral_to_hex_string<String, true>(std::forward<Arg>(arg)); + if (flags & with_width && ret.size() < width) { + ret = String(width - ret.size(), ' ') + ret; + } + } + else if (type == 'X') { + ret = integral_to_hex_string<String, false>(std::forward<Arg>(arg)); + if (flags & with_width && ret.size() < width) { + ret = String(width - ret.size(), ' ') + ret; + } + } + else if (type == 'p') { + ret = pointer_to_string<String>(std::forward<Arg>(arg)); + if (flags & with_width && ret.size() < width) { + ret = String(width - ret.size(), ' ') + ret; + } + } + else { + assert(0); + } + } + else { + ret = extract_arg<String>(flags, width, type, arg_n - 1, std::forward<Args>(args)...); + } + + return ret; +} + +template<typename String, typename... Args> +void process_arg(String const& fmt, typename String::size_type & pos, String& ret, size_t& arg_n, Args&&... args) +{ + ++pos; + + // Get literal percent out of the way + if (fmt[pos] == '%') { + ret += '%'; + ++pos; + return; + } + +parse_start: + char flags{}; + while (true) { + if (fmt[pos] == '0') { + flags |= pad_0; + } + else if (fmt[pos] == ' ') { + flags |= pad_blank; + } + else { + break; + } + ++pos; + } + + // Field width + size_t width{}; + while (fmt[pos] >= '0' && fmt[pos] <= '9') { + flags |= with_width; + width *= 10; + width += fmt[pos] - '0'; + ++pos; + } + if (width > 10000) { + assert(0); + width = 10000; + } + + if (fmt[pos] == '$') { + // Positional argument, start over + arg_n = width - 1; + ++pos; + goto parse_start; + } + + // Ignore length modifier + while (true) { + auto c = fmt[pos]; + if (c == 'h' || c == 'l' || c == 'L' || c == 'j' || c == 'z' || c == 't') { + ++pos; + } + else { + break; + } + } + + assert(arg_n < sizeof...(args)); + if (arg_n >= sizeof...(args)) { + ++pos; + return; + } + + auto const type = fmt[pos++]; + + ret += extract_arg<String>(flags, width, type, arg_n++, std::forward<Args>(args)...); + + // Now we're ready to print! +} + +} +/// \endcond + +/** \brief A simple type-safe sprintf replacement +* +* Only partially implements the format specifiers for the printf family of C functions: +* +* \li Positional arguments +* \li Supported flags: 0, ' ' +* \li Field widths are supported as decimal integers not exceeding 10k, longer widths are truncated +* \li precision is ignored +* \li Supported types: d, i, u, s, x, X, p +* +* For string arguments, mixing char*, wchar_t*, std::string and std::wstring is allowed. +* +* Asserts if unsupported types are passed or if the types don't match the arguments. Fails gracefully with NDEBUG. +* +* Example: +* +* \code +* std::string s = fz::printf("%2$s %1$s", "foo", std::wstring("bar"); +* assert(s == "bar foo"); // This is true +* \endcode +*/ +template<typename String, typename... Args> +String sprintf(String const& fmt, Args&&... args) +{ + String ret; + + // Find % characters + typename String::size_type start = 0, pos; + size_t arg_n{}; + while ((pos = fmt.find('%', start)) != String::npos) { + + // Copy segment preceeding the % + ret += fmt.substr(start, pos - start); + + detail::process_arg(fmt, pos, ret, arg_n, std::forward<Args>(args)...); + + start = pos; + } + + // Copy remainder of string + ret += fmt.substr(start); + + return ret; +} + +template<typename... Args> +std::string sprintf(char const* fmt, Args&&... args) +{ + return sprintf(std::string(fmt), std::forward<Args>(args)...); +} + +template<typename... Args> +std::wstring sprintf(wchar_t const* fmt, Args&&... args) +{ + return sprintf(std::wstring(fmt), std::forward<Args>(args)...); +} + +} + +#endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libfilezilla-0.5.3/lib/libfilezilla/glue/wx.hpp new/libfilezilla-0.6.1/lib/libfilezilla/glue/wx.hpp --- old/libfilezilla-0.5.3/lib/libfilezilla/glue/wx.hpp 2015-11-19 14:20:07.000000000 +0100 +++ new/libfilezilla-0.6.1/lib/libfilezilla/glue/wx.hpp 2016-07-20 10:41:55.000000000 +0200 @@ -3,6 +3,7 @@ #include <wx/string.h> +#include "../format.hpp" #include "../string.hpp" inline std::wstring to_wstring(wxString const& s) { return s.ToStdWstring(); } @@ -23,6 +24,18 @@ { return to_native(in.ToStdWstring()); } + +inline std::string to_utf8(wxString const& s) +{ + return to_utf8(s.ToStdWstring()); +} + +template<typename... Args> +std::wstring sprintf(wxString const& fmt, Args&&... args) +{ + return sprintf(fmt.ToStdWstring(), std::forward<Args>(args)...); +} + } #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libfilezilla-0.5.3/lib/libfilezilla/string.hpp new/libfilezilla-0.6.1/lib/libfilezilla/string.hpp --- old/libfilezilla-0.5.3/lib/libfilezilla/string.hpp 2016-06-20 10:08:07.000000000 +0200 +++ new/libfilezilla-0.6.1/lib/libfilezilla/string.hpp 2016-07-20 10:41:55.000000000 +0200 @@ -106,6 +106,14 @@ /// Returns identity, that way to_wstring can be called with native_string. inline std::wstring FZ_PUBLIC_SYMBOL to_wstring(std::wstring const& in) { return in; } +/// Converts from arithmetic type to std::wstring +template<typename Arg> +inline typename std::enable_if<std::is_arithmetic<std::decay_t<Arg>>::value, std::wstring>::type to_wstring(Arg && arg) +{ + return std::to_wstring(std::forward<Arg>(arg)); +} + + /** \brief Converts from std::string in UTF-8 into std::wstring * * \return the converted string on success. On failure an empty string is returned. @@ -123,6 +131,14 @@ /// Returns identity, that way to_string can be called with native_string. inline std::string FZ_PUBLIC_SYMBOL to_string(std::string const& in) { return in; } +/// Converts from arithmetic type to std::string +template<typename Arg> +inline typename std::enable_if<std::is_arithmetic<std::decay_t<Arg>>::value, std::string>::type to_string(Arg && arg) +{ + return std::to_string(std::forward<Arg>(arg)); +} + + /// Returns length of 0-terminated character sequence. Works with both narrow and wide-characters. template<typename Char> size_t strlen(Char const* str) { @@ -170,25 +186,25 @@ * * Undefined output if input is less than 0 or larger than 15 */ -template<typename Char = char> +template<typename Char = char, bool Lowercase = true> Char int_to_hex_char(int d) { if (d > 9) { - return 'a' + d - 10; + return (Lowercase ? 'a' : 'A') + d - 10; } else { return '0' + d; } } -/** \brief Convert integer to string. */ -template<typename String, typename Int> -inline typename std::enable_if<std::is_same<String, std::string>::value, std::string>::type -convert(Int i) { return std::to_string(i); }; - -template<typename String, typename Int> -inline typename std::enable_if<std::is_same<String, std::wstring>::value, std::wstring>::type -convert(Int i) { return std::to_wstring(i); }; +/// Calls either fz::to_string or fz::to_wstring depending on the passed template argument +template<typename String, typename Arg> +inline auto toString(Arg&& arg) -> typename std::enable_if<std::is_same<String, std::string>::value, decltype(to_string(std::forward<Arg>(arg)))>::type +{ return to_string(std::forward<Arg>(arg)); } + +template<typename String, typename Arg> +inline auto toString(Arg&& arg) -> typename std::enable_if<std::is_same<String, std::wstring>::value, decltype(to_wstring(std::forward<Arg>(arg)))>::type +{ return to_wstring(std::forward<Arg>(arg)); } #if !defined(fzT) || defined(DOXYGEN) #ifdef FZ_WINDOWS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libfilezilla-0.5.3/lib/libfilezilla/version.hpp new/libfilezilla-0.6.1/lib/libfilezilla/version.hpp --- old/libfilezilla-0.5.3/lib/libfilezilla/version.hpp 2016-06-20 10:12:36.000000000 +0200 +++ new/libfilezilla-0.6.1/lib/libfilezilla/version.hpp 2016-07-27 14:08:41.000000000 +0200 @@ -9,15 +9,15 @@ #include <tuple> /// \brief Version string of the libfilezilla headers -#define LIBFILEZILLA_VERSION "0.5.3" +#define LIBFILEZILLA_VERSION "0.6.1" #define LIBFILEZILLA_VERSION_MAJOR 0 -#define LIBFILEZILLA_VERSION_MINOR 5 -#define LIBFILEZILLA_VERSION_MICRO 3 +#define LIBFILEZILLA_VERSION_MINOR 6 +#define LIBFILEZILLA_VERSION_MICRO 1 #define LIBFILEZILLA_VERSION_NANO 0 /// \brief Suffix string, e.g. "rc1" -#define LIBFILEZILLA_VERSION_SUFFIX "0.5.3" +#define LIBFILEZILLA_VERSION_SUFFIX "0.6.1" namespace fz { /// \brief Get version string of libfilezilla diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libfilezilla-0.5.3/lib/libfilezilla.vcxproj new/libfilezilla-0.6.1/lib/libfilezilla.vcxproj --- old/libfilezilla-0.5.3/lib/libfilezilla.vcxproj 2016-02-21 11:35:46.000000000 +0100 +++ new/libfilezilla-0.6.1/lib/libfilezilla.vcxproj 2016-07-05 09:30:27.000000000 +0200 @@ -206,6 +206,7 @@ <ClInclude Include="libfilezilla\event_handler.hpp" /> <ClInclude Include="libfilezilla\event_loop.hpp" /> <ClInclude Include="libfilezilla\file.hpp" /> + <ClInclude Include="libfilezilla\format.hpp" /> <ClInclude Include="libfilezilla\iputils.hpp" /> <ClInclude Include="libfilezilla\libfilezilla.hpp" /> <ClInclude Include="libfilezilla\local_filesys.hpp" /> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libfilezilla-0.5.3/lib/mutex.cpp new/libfilezilla-0.6.1/lib/mutex.cpp --- old/libfilezilla-0.5.3/lib/mutex.cpp 2015-11-02 14:47:31.000000000 +0100 +++ new/libfilezilla-0.6.1/lib/mutex.cpp 2016-07-20 10:41:55.000000000 +0200 @@ -49,7 +49,7 @@ { #ifdef FZ_WINDOWS (void)recursive; // Critical sections are always recursive - InitializeCriticalSection(&m_); + InitializeCriticalSectionEx(&m_, 0, CRITICAL_SECTION_NO_DEBUG_INFO); #else pthread_mutex_init(&m_, get_mutex_attributes(recursive)); #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libfilezilla-0.5.3/lib/process.cpp new/libfilezilla-0.6.1/lib/process.cpp --- old/libfilezilla-0.5.3/lib/process.cpp 2015-11-02 14:47:31.000000000 +0100 +++ new/libfilezilla-0.6.1/lib/process.cpp 2016-07-20 10:41:55.000000000 +0200 @@ -158,6 +158,12 @@ DWORD read = 0; BOOL res = ReadFile(out_.read_, buffer, len, &read, 0); if (!res) { +#if FZ_WINDOWS + // ERROR_BROKEN_PIPE indicated EOF. + if (GetLastError() == ERROR_BROKEN_PIPE) { + return 0; + } +#endif return -1; } return read; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libfilezilla-0.5.3/lib/string.cpp new/libfilezilla-0.6.1/lib/string.cpp --- old/libfilezilla-0.5.3/lib/string.cpp 2016-06-20 10:08:07.000000000 +0200 +++ new/libfilezilla-0.6.1/lib/string.cpp 2016-07-27 14:03:01.000000000 +0200 @@ -95,6 +95,55 @@ // Depending which one is used, declare iconv_second_arg_type as either char* or char const* extern "C" typedef size_t (*iconv_prototype_with_const)(iconv_t, char const**, size_t *, char**, size_t *); typedef std::conditional<std::is_same<decltype(&iconv), iconv_prototype_with_const>::value, char const*, char*>::type iconv_second_arg_type; + +namespace { +// On some platforms, e.g. those derived from SunOS, iconv does not understand "WCHAR_T", so we +// need to guess an encoding. +// On other platforms, WCHAR_T results in iconv() doing endless loops, such as OS X. +char const* const calc_wchar_t_encoding() +{ + auto try_encoding = [](char const* const encoding) -> bool { + iconv_t cd = iconv_open(encoding, "UTF-8"); + if (cd == reinterpret_cast<iconv_t>(-1)) { + return false; + } + iconv_close(cd); + return true; + }; + + // Explicitly specify endianess, otherwise we'll get a BOM prefixed to everything + int const i = 1; + char const* p = reinterpret_cast<char const*>(&i); + bool little_endian = p[0] == 1; + + if (sizeof(wchar_t) == 4) { + if (little_endian && try_encoding("UTF-32LE")) { + return "UTF-32LE"; + } + if (!little_endian && try_encoding("UTF-32BE")) { + return "UTF-32BE"; + } + } + else if (sizeof(wchar_t) == 2) { + if (little_endian && try_encoding("UTF-16LE")) { + return "UTF-16LE"; + } + if (!little_endian && try_encoding("UTF-16BE")) { + return "UTF-16BE"; + } + } + + // Oh dear... + // WCHAR_T is our last, best hope. + return "WCHAR_T"; +} + +char const* wchar_t_encoding() +{ + static char const* const encoding = calc_wchar_t_encoding(); + return encoding; +} +} #endif std::wstring to_wstring_from_utf8(std::string const& in) @@ -108,10 +157,10 @@ if (len > 0) { ret.resize(len); wchar_t* out_p = &ret[0]; - MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, in_p, len, out_p, len); + MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, in_p, static_cast<int>(in.size()), out_p, len); } #else - iconv_t cd = iconv_open("WCHAR_T", "UTF-8"); + iconv_t cd = iconv_open(wchar_t_encoding(), "UTF-8"); if (cd != reinterpret_cast<iconv_t>(-1)) { auto in_p = const_cast<iconv_second_arg_type>(in.c_str()); size_t in_len = in.size(); @@ -172,10 +221,10 @@ if (len > 0) { ret.resize(len); char* out_p = &ret[0]; - WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, in_p, len, out_p, len, 0, 0); + WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, in_p, static_cast<int>(in.size()), out_p, len, 0, 0); } #else - iconv_t cd = iconv_open("UTF-8", "WCHAR_T"); + iconv_t cd = iconv_open("UTF-8", wchar_t_encoding()); if (cd != reinterpret_cast<iconv_t>(-1)) { auto in_p = reinterpret_cast<iconv_second_arg_type>(const_cast<wchar_t*>(in.c_str())); size_t in_len = in.size() * sizeof(wchar_t); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libfilezilla-0.5.3/tests/Makefile.am new/libfilezilla-0.6.1/tests/Makefile.am --- old/libfilezilla-0.5.3/tests/Makefile.am 2016-02-21 11:35:46.000000000 +0100 +++ new/libfilezilla-0.6.1/tests/Makefile.am 2016-07-05 09:30:27.000000000 +0200 @@ -6,6 +6,7 @@ test_SOURCES = test.cpp \ dispatch.cpp \ eventloop.cpp \ + format.cpp \ iputils.cpp \ smart_pointer.cpp \ string.cpp \ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libfilezilla-0.5.3/tests/Makefile.in new/libfilezilla-0.6.1/tests/Makefile.in --- old/libfilezilla-0.5.3/tests/Makefile.in 2016-06-20 10:12:34.000000000 +0200 +++ new/libfilezilla-0.6.1/tests/Makefile.in 2016-07-27 14:08:39.000000000 +0200 @@ -107,9 +107,9 @@ CONFIG_CLEAN_VPATH_FILES = am__EXEEXT_1 = test$(EXEEXT) am_test_OBJECTS = test-test.$(OBJEXT) test-dispatch.$(OBJEXT) \ - test-eventloop.$(OBJEXT) test-iputils.$(OBJEXT) \ - test-smart_pointer.$(OBJEXT) test-string.$(OBJEXT) \ - test-time.$(OBJEXT) + test-eventloop.$(OBJEXT) test-format.$(OBJEXT) \ + test-iputils.$(OBJEXT) test-smart_pointer.$(OBJEXT) \ + test-string.$(OBJEXT) test-time.$(OBJEXT) test_OBJECTS = $(am_test_OBJECTS) am__DEPENDENCIES_1 = AM_V_lt = $(am__v_lt_@AM_V@) @@ -543,6 +543,7 @@ test_SOURCES = test.cpp \ dispatch.cpp \ eventloop.cpp \ + format.cpp \ iputils.cpp \ smart_pointer.cpp \ string.cpp \ @@ -609,6 +610,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-dispatch.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-eventloop.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-format.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-iputils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-smart_pointer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-string.Po@am__quote@ @@ -678,6 +680,20 @@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test-eventloop.obj `if test -f 'eventloop.cpp'; then $(CYGPATH_W) 'eventloop.cpp'; else $(CYGPATH_W) '$(srcdir)/eventloop.cpp'; fi` +test-format.o: format.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test-format.o -MD -MP -MF $(DEPDIR)/test-format.Tpo -c -o test-format.o `test -f 'format.cpp' || echo '$(srcdir)/'`format.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test-format.Tpo $(DEPDIR)/test-format.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='format.cpp' object='test-format.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test-format.o `test -f 'format.cpp' || echo '$(srcdir)/'`format.cpp + +test-format.obj: format.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test-format.obj -MD -MP -MF $(DEPDIR)/test-format.Tpo -c -o test-format.obj `if test -f 'format.cpp'; then $(CYGPATH_W) 'format.cpp'; else $(CYGPATH_W) '$(srcdir)/format.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test-format.Tpo $(DEPDIR)/test-format.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='format.cpp' object='test-format.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test-format.obj `if test -f 'format.cpp'; then $(CYGPATH_W) 'format.cpp'; else $(CYGPATH_W) '$(srcdir)/format.cpp'; fi` + test-iputils.o: iputils.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test-iputils.o -MD -MP -MF $(DEPDIR)/test-iputils.Tpo -c -o test-iputils.o `test -f 'iputils.cpp' || echo '$(srcdir)/'`iputils.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/test-iputils.Tpo $(DEPDIR)/test-iputils.Po diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libfilezilla-0.5.3/tests/format.cpp new/libfilezilla-0.6.1/tests/format.cpp --- old/libfilezilla-0.5.3/tests/format.cpp 1970-01-01 01:00:00.000000000 +0100 +++ new/libfilezilla-0.6.1/tests/format.cpp 2016-07-20 10:41:55.000000000 +0200 @@ -0,0 +1,102 @@ +#include "libfilezilla/format.hpp" + +#include "test_utils.hpp" +/* + * This testsuite asserts the correctness of the + * string formatting functions + */ + +class format_test : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE(format_test); + CPPUNIT_TEST(test_sprintf); + CPPUNIT_TEST_SUITE_END(); + +public: + void setUp() {} + void tearDown() {} + + void test_sprintf(); +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(format_test); + +void format_test::test_sprintf() +{ + CPPUNIT_ASSERT_EQUAL(std::string("foo"), fz::sprintf("foo")); + CPPUNIT_ASSERT_EQUAL(std::string("foo % bar"), fz::sprintf("foo %% bar")); + + CPPUNIT_ASSERT_EQUAL(std::string("foo bar"), fz::sprintf("foo %s", "bar")); + CPPUNIT_ASSERT_EQUAL(std::string("foo bar"), fz::sprintf("foo %s", L"bar")); + CPPUNIT_ASSERT_EQUAL(std::string("foo bar"), fz::sprintf("foo %s", std::string("bar"))); + CPPUNIT_ASSERT_EQUAL(std::string("foo bar"), fz::sprintf("foo %s", std::wstring(L"bar"))); + + CPPUNIT_ASSERT_EQUAL(std::string(" "), fz::sprintf("%4s", " ")); + + CPPUNIT_ASSERT_EQUAL(std::string("0"), fz::sprintf("%d", 0)); + CPPUNIT_ASSERT_EQUAL(std::string(" 0"), fz::sprintf("%4d", 0)); + CPPUNIT_ASSERT_EQUAL(std::string("0000"), fz::sprintf("%04d", 0)); + CPPUNIT_ASSERT_EQUAL(std::string(" 0"), fz::sprintf("% 4d", 0)); + CPPUNIT_ASSERT_EQUAL(std::string(" 000"), fz::sprintf("% 04d", 0)); + CPPUNIT_ASSERT_EQUAL(std::string(" 000"), fz::sprintf("%0 4d", 0)); + + CPPUNIT_ASSERT_EQUAL(std::string("0"), fz::sprintf("%0d", 0)); + CPPUNIT_ASSERT_EQUAL(std::string(" 0"), fz::sprintf("% 0d", 0)); + CPPUNIT_ASSERT_EQUAL(std::string(" 0"), fz::sprintf("% d", 0)); + + CPPUNIT_ASSERT_EQUAL(std::string("1"), fz::sprintf("%d", 1)); + CPPUNIT_ASSERT_EQUAL(std::string(" 1"), fz::sprintf("%4d", 1)); + CPPUNIT_ASSERT_EQUAL(std::string("0001"), fz::sprintf("%04d", 1)); + CPPUNIT_ASSERT_EQUAL(std::string(" 1"), fz::sprintf("% 4d", 1)); + CPPUNIT_ASSERT_EQUAL(std::string(" 001"), fz::sprintf("% 04d", 1)); + CPPUNIT_ASSERT_EQUAL(std::string(" 001"), fz::sprintf("%0 4d", 1)); + + CPPUNIT_ASSERT_EQUAL(std::string("123"), fz::sprintf("%d", 123)); + CPPUNIT_ASSERT_EQUAL(std::string(" 123"), fz::sprintf("%4d", 123)); + CPPUNIT_ASSERT_EQUAL(std::string("0123"), fz::sprintf("%04d", 123)); + CPPUNIT_ASSERT_EQUAL(std::string(" 123"), fz::sprintf("% 4d", 123)); + CPPUNIT_ASSERT_EQUAL(std::string(" 123"), fz::sprintf("% 04d", 123)); + CPPUNIT_ASSERT_EQUAL(std::string(" 123"), fz::sprintf("%0 4d", 123)); + + CPPUNIT_ASSERT_EQUAL(std::string("1234"), fz::sprintf("%d", 1234)); + CPPUNIT_ASSERT_EQUAL(std::string("1234"), fz::sprintf("%4d", 1234)); + CPPUNIT_ASSERT_EQUAL(std::string("1234"), fz::sprintf("%04d", 1234)); + CPPUNIT_ASSERT_EQUAL(std::string(" 1234"), fz::sprintf("% 4d", 1234)); + CPPUNIT_ASSERT_EQUAL(std::string(" 1234"), fz::sprintf("% 04d", 1234)); + CPPUNIT_ASSERT_EQUAL(std::string(" 1234"), fz::sprintf("%0 4d", 1234)); + + CPPUNIT_ASSERT_EQUAL(std::string("12345"), fz::sprintf("%d", 12345)); + CPPUNIT_ASSERT_EQUAL(std::string("12345"), fz::sprintf("%4d", 12345)); + CPPUNIT_ASSERT_EQUAL(std::string("12345"), fz::sprintf("%04d", 12345)); + CPPUNIT_ASSERT_EQUAL(std::string(" 12345"), fz::sprintf("% 4d", 12345)); + CPPUNIT_ASSERT_EQUAL(std::string(" 12345"), fz::sprintf("% 04d", 12345)); + CPPUNIT_ASSERT_EQUAL(std::string(" 12345"), fz::sprintf("%0 4d", 12345)); + + CPPUNIT_ASSERT_EQUAL(std::string("-42"), fz::sprintf("%d", -42)); + CPPUNIT_ASSERT_EQUAL(std::string("-42"), fz::sprintf("%d", -42)); + CPPUNIT_ASSERT_EQUAL(std::string("-42"), fz::sprintf("%0d", -42)); + CPPUNIT_ASSERT_EQUAL(std::string("-42"), fz::sprintf("% d", -42)); + CPPUNIT_ASSERT_EQUAL(std::string("-42"), fz::sprintf("% 0d", -42)); + + CPPUNIT_ASSERT_EQUAL(std::string(" -42"), fz::sprintf("%4d", -42)); + CPPUNIT_ASSERT_EQUAL(std::string(" -42"), fz::sprintf("%4d", -42)); + CPPUNIT_ASSERT_EQUAL(std::string("-042"), fz::sprintf("%04d", -42)); + CPPUNIT_ASSERT_EQUAL(std::string(" -42"), fz::sprintf("% 4d", -42)); + CPPUNIT_ASSERT_EQUAL(std::string("-042"), fz::sprintf("% 04d", -42)); + + CPPUNIT_ASSERT_EQUAL(std::string("foo 7 foo"), fz::sprintf("%2$s %1$d %2$s", 7, "foo")); + + CPPUNIT_ASSERT_EQUAL(std::string("0"), fz::sprintf("%x", 0)); + CPPUNIT_ASSERT_EQUAL(std::string("23bf0a"), fz::sprintf("%x", 2342666)); + CPPUNIT_ASSERT_EQUAL(std::string("23BF0A"), fz::sprintf("%X", 2342666)); + CPPUNIT_ASSERT_EQUAL(std::string("23bf0a"), fz::sprintf("%0x", 2342666)); + CPPUNIT_ASSERT_EQUAL(std::string("23bf0a"), fz::sprintf("% x", 2342666)); + CPPUNIT_ASSERT_EQUAL(std::string("23bf0a"), fz::sprintf("% 0x", 2342666)); + + CPPUNIT_ASSERT_EQUAL(std::string(" 0"), fz::sprintf("%4x", 0)); + CPPUNIT_ASSERT_EQUAL(std::string("23bf0a"), fz::sprintf("%4x", 2342666)); + CPPUNIT_ASSERT_EQUAL(std::string("23BF0A"), fz::sprintf("%4X", 2342666)); + CPPUNIT_ASSERT_EQUAL(std::string("23bf0a"), fz::sprintf("%04x", 2342666)); + CPPUNIT_ASSERT_EQUAL(std::string("23bf0a"), fz::sprintf("% 4x", 2342666)); + CPPUNIT_ASSERT_EQUAL(std::string("23bf0a"), fz::sprintf("% 04x", 2342666)); +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libfilezilla-0.5.3/tests/string.cpp new/libfilezilla-0.6.1/tests/string.cpp --- old/libfilezilla-0.5.3/tests/string.cpp 2016-01-31 11:35:01.000000000 +0100 +++ new/libfilezilla-0.6.1/tests/string.cpp 2016-07-27 14:03:01.000000000 +0200 @@ -11,6 +11,7 @@ CPPUNIT_TEST_SUITE(string_test); CPPUNIT_TEST(test_conversion); CPPUNIT_TEST(test_conversion2); + CPPUNIT_TEST(test_conversion_utf8); CPPUNIT_TEST_SUITE_END(); public: @@ -19,6 +20,7 @@ void test_conversion(); void test_conversion2(); + void test_conversion_utf8(); }; CPPUNIT_TEST_SUITE_REGISTRATION(string_test); @@ -43,7 +45,7 @@ void string_test::test_conversion2() { - wchar_t p[] = { 'M', 'o', 't', 0xf6, 'r', 'h', 'e', 'a', 'd', 0 }; + wchar_t const p[] = { 'M', 'o', 't', 0xf6, 'r', 'h', 'e', 'a', 'd', 0 }; std::wstring const w(p); std::string const s = fz::to_string(w); @@ -54,3 +56,22 @@ ASSERT_EQUAL(w, w2); } + +void string_test::test_conversion_utf8() +{ + wchar_t const p[] = { 'M', 'o', 't', 0xf6, 'r', 'h', 'e', 'a', 'd', 0 }; + unsigned char const p_utf8[] = { 'M', 'o', 't', 0xc3, 0xb6, 'r', 'h', 'e', 'a', 'd', 0 }; + + std::wstring const w(p); + std::string const u(reinterpret_cast<char const*>(p_utf8)); + + std::string const s = fz::to_utf8(w); + + CPPUNIT_ASSERT(s.size() >= w.size()); + + ASSERT_EQUAL(s, u); + + std::wstring const w2 = fz::to_wstring_from_utf8(s); + + ASSERT_EQUAL(w, w2); +}
