Hello community,
here is the log from the commit of package libyui for openSUSE:Factory checked in at 2018-08-02 14:55:52
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libyui (Old)
and /work/SRC/openSUSE:Factory/.libyui.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libyui"
Thu Aug 2 14:55:52 2018 rev:35 rq:626654 version:3.4.2
Changes:
--------
--- /work/SRC/openSUSE:Factory/libyui/libyui.changes 2018-05-17 19:31:52.962410950 +0200
+++ /work/SRC/openSUSE:Factory/.libyui.new/libyui.changes 2018-08-02 14:56:00.672062754 +0200
@@ -1,0 +2,8 @@
+Thu Jul 26 07:45:20 UTC 2018 - lslezak@suse.cz
+
+- Improved the FSize class to handle arbitrary sizes, use the boost
+ multiprecision library instead of `long long` which overflows for
+ values > 8EiB (bsc#991090)
+- 3.4.2
+
+-------------------------------------------------------------------
Old:
----
libyui-3.4.1.tar.bz2
New:
----
libyui-3.4.2.tar.bz2
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ libyui-doc.spec ++++++
--- /var/tmp/diff_new_pack.1vw1Ed/_old 2018-08-02 14:56:01.432064026 +0200
+++ /var/tmp/diff_new_pack.1vw1Ed/_new 2018-08-02 14:56:01.436064032 +0200
@@ -17,10 +17,10 @@
%define parent libyui
-%define so_version 8
+%define so_version 9
Name: %{parent}-doc
-Version: 3.4.1
+Version: 3.4.2
Release: 0
Source: %{parent}-%{version}.tar.bz2
++++++ libyui.spec ++++++
--- /var/tmp/diff_new_pack.1vw1Ed/_old 2018-08-02 14:56:01.452064059 +0200
+++ /var/tmp/diff_new_pack.1vw1Ed/_new 2018-08-02 14:56:01.452064059 +0200
@@ -17,15 +17,20 @@
Name: libyui
-Version: 3.4.1
+Version: 3.4.2
Release: 0
Source: %{name}-%{version}.tar.bz2
-%define so_version 8
+%define so_version 9
%define bin_name %{name}%{so_version}
+# optionally build with code coverage reporting,
+# this uses debug build, do not use in production!
+%bcond_with coverage
+
%if 0%{?suse_version} > 1325
BuildRequires: libboost_headers-devel
+BuildRequires: libboost_test-devel
%else
BuildRequires: boost-devel
%endif
@@ -33,6 +38,12 @@
BuildRequires: gcc-c++
BuildRequires: pkg-config
+%if %{with coverage}
+# normally the coverage feature should not be used out of CI
+# but to be on the safe side...
+BuildRequires: lcov
+%endif
+
Url: http://github.com/libyui/
Summary: GUI-abstraction library
License: LGPL-2.1 or LGPL-3.0
@@ -70,6 +81,7 @@
%if 0%{?suse_version} > 1325
Requires: libboost_headers-devel
+Requires: libboost_test-devel
%else
Requires: boost-devel
%endif
@@ -99,29 +111,41 @@
%build
./bootstrap.sh
-
-export CFLAGS="$RPM_OPT_FLAGS -DNDEBUG $(getconf LFS_CFLAGS)"
-export CXXFLAGS="$RPM_OPT_FLAGS -DNDEBUG $(getconf LFS_CFLAGS)"
-
mkdir build
cd build
+%if %{with coverage}
+CMAKE_OPTS="-DCMAKE_BUILD_TYPE=DEBUG -DENABLE_CODE_COVERAGE=ON"
+# the debug build type is incompatible with the default $RPM_OPT_FLAGS,
+# do not use them
+export CFLAGS="-DNDEBUG $(getconf LFS_CFLAGS)"
+export CXXFLAGS="-DNDEBUG $(getconf LFS_CFLAGS)"
+%else
+export CFLAGS="$RPM_OPT_FLAGS -DNDEBUG $(getconf LFS_CFLAGS)"
+export CXXFLAGS="$RPM_OPT_FLAGS -DNDEBUG $(getconf LFS_CFLAGS)"
%if %{?_with_debug:1}%{!?_with_debug:0}
-cmake .. \
- -DYPREFIX=%{_prefix} \
- -DDOC_DIR=%{_docdir} \
- -DLIB_DIR=%{_lib} \
- -DCMAKE_BUILD_TYPE=RELWITHDEBINFO
+CMAKE_OPTS="-DCMAKE_BUILD_TYPE=RELWITHDEBINFO"
%else
+CMAKE_OPTS="-DCMAKE_BUILD_TYPE=RELEASE"
+%endif
+%endif
+
cmake .. \
-DYPREFIX=%{_prefix} \
-DDOC_DIR=%{_docdir} \
-DLIB_DIR=%{_lib} \
- -DCMAKE_BUILD_TYPE=RELEASE
-%endif
+ $CMAKE_OPTS
make %{?jobs:-j%jobs}
+%check
+cd build
+make test
+%if %{with coverage}
+# generate code coverage data
+make coverage
+%endif
+
%install
cd build
make install DESTDIR="$RPM_BUILD_ROOT"
++++++ libyui-3.4.1.tar.bz2 -> libyui-3.4.2.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libyui-3.4.1/.travis.yml new/libyui-3.4.2/.travis.yml
--- old/libyui-3.4.1/.travis.yml 2018-05-14 14:10:38.000000000 +0200
+++ new/libyui-3.4.2/.travis.yml 2018-07-31 09:50:54.000000000 +0200
@@ -8,4 +8,4 @@
script:
# the "libyui-travis" script is included in the base libyui/devel image
# see https://github.com/libyui/docker-devel/blob/master/libyui-travis
- - docker run -it libyui-image libyui-travis
+ - docker run -it -e COVERALLS_TOKEN="$COVERALLS_TOKEN" -e TRAVIS_JOB_ID="$TRAVIS_JOB_ID" libyui-image libyui-travis
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libyui-3.4.1/Makefile.cvs new/libyui-3.4.2/Makefile.cvs
--- old/libyui-3.4.1/Makefile.cvs 2018-05-14 14:10:38.000000000 +0200
+++ new/libyui-3.4.2/Makefile.cvs 2018-07-31 09:50:54.000000000 +0200
@@ -2,6 +2,11 @@
# Makefile.cvs
#
+# enable coverage if $COVERAGE is set to 1
+ifeq ($(COVERAGE), 1)
+EXTRA_PARAMS := -DENABLE_CODE_COVERAGE=ON
+endif
+
all: configure
configure: clean
@@ -9,7 +14,7 @@
mkdir build ; \
cd build ; \
cmake .. \
- -DCMAKE_BUILD_TYPE=RELEASE
+ -DCMAKE_BUILD_TYPE=RELEASE $(EXTRA_PARAMS)
install: configure
cd build ; \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libyui-3.4.1/PROJECTINFO.cmake new/libyui-3.4.2/PROJECTINFO.cmake
--- old/libyui-3.4.1/PROJECTINFO.cmake 2018-05-14 14:10:38.000000000 +0200
+++ new/libyui-3.4.2/PROJECTINFO.cmake 2018-07-31 09:50:54.000000000 +0200
@@ -4,7 +4,7 @@
##### MAKE ALL NEEDED CHANGES HERE #####
-SET( SUBDIRS src examples )
+SET( SUBDIRS src examples tests )
SET( LIB_DEPS Boost )
SET( LIB_LINKER dl pthread )
SET( EXTRA_INCLUDES ) # set include-dir which are not picked by CMake automagically here.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libyui-3.4.1/README.md new/libyui-3.4.2/README.md
--- old/libyui-3.4.1/README.md 2018-05-14 14:10:38.000000000 +0200
+++ new/libyui-3.4.2/README.md 2018-07-31 09:50:54.000000000 +0200
@@ -1,6 +1,9 @@
# LibYUI - The Base Library
[![Build Status](https://travis-ci.org/libyui/libyui.svg?branch=master)](https://travis-ci.org/libyui/libyui)
+[![Coverage Status](
+https://coveralls.io/repos/github/libyui/libyui/badge.svg?branch=master)](
+https://coveralls.io/github/libyui/libyui?branch=master)
Libyui is a widget abstraction library providing Qt, GTK and ncurses
frontends. Originally it was developed for [YaST](https://yast.github.io/)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libyui-3.4.1/VERSION.cmake new/libyui-3.4.2/VERSION.cmake
--- old/libyui-3.4.1/VERSION.cmake 2018-05-14 14:10:38.000000000 +0200
+++ new/libyui-3.4.2/VERSION.cmake 2018-07-31 09:50:54.000000000 +0200
@@ -1,6 +1,6 @@
SET( VERSION_MAJOR "3")
SET( VERSION_MINOR "4" )
-SET( VERSION_PATCH "1" )
+SET( VERSION_PATCH "2" )
SET( VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}${GIT_SHA1_VERSION}" )
##### This is need for the libyui core, ONLY.
@@ -8,7 +8,7 @@
# Currently you must also change so_version in libyui.spec
# *and also in **all** other* libyui-*.spec files in the other repositories.
# Yes, such a design is suboptimal.
-SET( SONAME_MAJOR "8" )
-SET( SONAME_MINOR "1" )
+SET( SONAME_MAJOR "9" )
+SET( SONAME_MINOR "0" )
SET( SONAME_PATCH "0" )
SET( SONAME "${SONAME_MAJOR}.${SONAME_MINOR}.${SONAME_PATCH}" )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libyui-3.4.1/buildtools/LibyuiCommon.cmake new/libyui-3.4.2/buildtools/LibyuiCommon.cmake
--- old/libyui-3.4.1/buildtools/LibyuiCommon.cmake 2018-05-14 14:10:38.000000000 +0200
+++ new/libyui-3.4.2/buildtools/LibyuiCommon.cmake 2018-07-31 09:50:54.000000000 +0200
@@ -58,6 +58,8 @@
OPTION( ENABLE_WERROR "Enable the -Werror compiler-flag?" ON )
OPTION( RESPECT_FLAGS "Shall I respect the system c/ldflags?" OFF )
OPTION( INSTALL_DOCS "Shall \"make install\" install the docs?" OFF )
+ OPTION( ENABLE_TESTS "Enable tests?" ON)
+ OPTION( ENABLE_CODE_COVERAGE "Enable code coverage report?" OFF)
ENDMACRO( SET_OPTIONS )
@@ -116,6 +118,59 @@
)
ENDIF( NOT BUILD_TYPE_PASSED )
+ IF ( ENABLE_TESTS OR ENABLE_CODE_COVERAGE)
+ ENABLE_TESTING()
+ # add a wrapper "tests" target, the builtin "test" cannot be extended :-(
+ ADD_CUSTOM_TARGET(tests
+ $(MAKE)
+ COMMAND $(MAKE) test
+ )
+ ENDIF ( ENABLE_TESTS OR ENABLE_CODE_COVERAGE)
+
+ IF ( ENABLE_CODE_COVERAGE )
+ # pass the coverage options to GCC
+ ADD_DEFINITIONS(--coverage)
+ LINK_LIBRARIES(--coverage)
+ # force debug build to not optimize the code, the optimized out code
+ # might be reported as not covered
+ SET( CMAKE_BUILD_TYPE DEBUG CACHE
+ STRING "set to DEBUG"
+ FORCE
+ )
+
+ FIND_PROGRAM( LCOV_PATH lcov )
+ FIND_PROGRAM( GENHTML_PATH genhtml )
+
+ IF(LCOV_PATH AND GENHTML_PATH)
+ # save the coverage data to coverage/ subdir
+ SET(COVERAGE_DATA "coverage/coverage.info")
+ ADD_CUSTOM_TARGET(coverage
+ # remove the previous coverage data
+ rm -rf coverage/*
+ COMMAND mkdir -p coverage
+ # collect the coverage data, ignore external files (/usr/include/...), ignore tests
+ COMMAND ${LCOV_PATH} --no-external --exclude '*/tests/*' -o ${COVERAGE_DATA} -c -d . -q
+ # generate the HTML coverage report
+ COMMAND ${GENHTML_PATH} -o coverage --legend --title "libyui code coverage" -q ${COVERAGE_DATA}
+ # print the coverage summary on the terminal
+ COMMAND ${LCOV_PATH} --list ${COVERAGE_DATA}
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+ COMMENT "Generating the code coverage report..."
+ )
+ # display a comment when finished
+ ADD_CUSTOM_COMMAND(TARGET coverage POST_BUILD
+ COMMAND ;
+ COMMENT "Code coverage gerated to ./coverage/index.html file."
+ )
+ # automatically collect code coverage after "tests" target is finished
+ ADD_CUSTOM_COMMAND(TARGET tests POST_BUILD
+ COMMAND $(MAKE) coverage
+ )
+ ELSE(LCOV_PATH AND GENHTML_PATH)
+ MESSAGE(FATAL_ERROR "lcov is not installed, code coverage report cannot be generated.")
+ ENDIF(LCOV_PATH AND GENHTML_PATH)
+ ENDIF ( ENABLE_CODE_COVERAGE )
+
SET( CMAKE_CXX_FLAGS_DEBUG "-O0 -g3" )
SET( CMAKE_C_FLAGS_DEBUG "-O0 -g3" )
SET( CMAKE_CXX_FLAGS_MINSIZEREL "-Os" )
@@ -566,6 +621,8 @@
ENDIF( ENABLE_DEBUG OR ${CMAKE_BUILD_TYPE} STREQUAL "RELWITHDEBINFO" OR ${CMAKE_BUILD_TYPE} STREQUAL "DEBUG" )
MESSAGE( STATUS " Build a static library, too: ${ENABLE_STATIC}" )
MESSAGE( STATUS " Build the examples, too: ${ENABLE_EXAMPLES}" )
+ MESSAGE( STATUS " Build the tests, too: ${ENABLE_TESTS}" )
+ MESSAGE( STATUS " Generate test code coverage: ${ENABLE_CODE_COVERAGE}" )
MESSAGE( STATUS "" )
IF( INSTALL_DOCS AND DOXYGEN_FOUND )
MESSAGE( STATUS "RUN `make docs` BEFORE `make install` !!!" )
@@ -723,3 +780,25 @@
)
ENDMACRO( PROCESS_EXAMPLES )
+
+
+
+MACRO( PROCESS_TESTS )
+
+ FIND_PACKAGE(Boost COMPONENTS unit_test_framework REQUIRED)
+ INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS} ../src ${CMAKE_INCLUDE_PATH} )
+ ADD_DEFINITIONS(-DBOOST_TEST_DYN_LINK -DTESTS_SRC_DIR="${CMAKE_CURRENT_SOURCE_DIR}" )
+
+ # expect the tests in *_test.cc files
+ FILE(GLOB unit_tests "*_test.cc")
+ FOREACH(unit_test ${unit_tests})
+ # strip the .cc suffix
+ GET_FILENAME_COMPONENT(unit_test_bin ${unit_test} NAME_WE)
+ # build the test executable
+ ADD_EXECUTABLE(${unit_test_bin} ${unit_test})
+ TARGET_LINK_LIBRARIES (${unit_test_bin} ${BASELIB} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY} )
+ # add it to the test suite
+ ADD_TEST(NAME ${unit_test_bin} COMMAND ${unit_test_bin})
+ ENDFOREACH(unit_test)
+
+ENDMACRO( PROCESS_TESTS )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libyui-3.4.1/package/libyui-doc.spec new/libyui-3.4.2/package/libyui-doc.spec
--- old/libyui-3.4.1/package/libyui-doc.spec 2018-05-14 14:10:38.000000000 +0200
+++ new/libyui-3.4.2/package/libyui-doc.spec 2018-07-31 09:50:54.000000000 +0200
@@ -17,10 +17,10 @@
%define parent libyui
-%define so_version 8
+%define so_version 9
Name: %{parent}-doc
-Version: 3.4.1
+Version: 3.4.2
Release: 0
Source: %{parent}-%{version}.tar.bz2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libyui-3.4.1/package/libyui.changes new/libyui-3.4.2/package/libyui.changes
--- old/libyui-3.4.1/package/libyui.changes 2018-05-14 14:10:38.000000000 +0200
+++ new/libyui-3.4.2/package/libyui.changes 2018-07-31 09:50:54.000000000 +0200
@@ -1,4 +1,12 @@
-------------------------------------------------------------------
+Thu Jul 26 07:45:20 UTC 2018 - lslezak@suse.cz
+
+- Improved the FSize class to handle arbitrary sizes, use the boost
+ multiprecision library instead of `long long` which overflows for
+ values > 8EiB (bsc#991090)
+- 3.4.2
+
+-------------------------------------------------------------------
Wed May 9 07:34:16 UTC 2018 - mliska@suse.cz
- Fix GCC 8 warning: -Werror=catch-value (boo#1084636).
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libyui-3.4.1/package/libyui.spec new/libyui-3.4.2/package/libyui.spec
--- old/libyui-3.4.1/package/libyui.spec 2018-05-14 14:10:38.000000000 +0200
+++ new/libyui-3.4.2/package/libyui.spec 2018-07-31 09:50:54.000000000 +0200
@@ -16,15 +16,20 @@
#
Name: libyui
-Version: 3.4.1
+Version: 3.4.2
Release: 0
Source: %{name}-%{version}.tar.bz2
-%define so_version 8
+%define so_version 9
%define bin_name %{name}%{so_version}
+# optionally build with code coverage reporting,
+# this uses debug build, do not use in production!
+%bcond_with coverage
+
%if 0%{?suse_version} > 1325
BuildRequires: libboost_headers-devel
+BuildRequires: libboost_test-devel
%else
BuildRequires: boost-devel
%endif
@@ -32,6 +37,12 @@
BuildRequires: gcc-c++
BuildRequires: pkg-config
+%if %{with coverage}
+# normally the coverage feature should not be used out of CI
+# but to be on the safe side...
+BuildRequires: lcov
+%endif
+
Url: http://github.com/libyui/
Summary: GUI-abstraction library
License: LGPL-2.1 or LGPL-3.0
@@ -69,6 +80,7 @@
%if 0%{?suse_version} > 1325
Requires: libboost_headers-devel
+Requires: libboost_test-devel
%else
Requires: boost-devel
%endif
@@ -98,29 +110,41 @@
%build
./bootstrap.sh
-
-export CFLAGS="$RPM_OPT_FLAGS -DNDEBUG $(getconf LFS_CFLAGS)"
-export CXXFLAGS="$RPM_OPT_FLAGS -DNDEBUG $(getconf LFS_CFLAGS)"
-
mkdir build
cd build
+%if %{with coverage}
+CMAKE_OPTS="-DCMAKE_BUILD_TYPE=DEBUG -DENABLE_CODE_COVERAGE=ON"
+# the debug build type is incompatible with the default $RPM_OPT_FLAGS,
+# do not use them
+export CFLAGS="-DNDEBUG $(getconf LFS_CFLAGS)"
+export CXXFLAGS="-DNDEBUG $(getconf LFS_CFLAGS)"
+%else
+export CFLAGS="$RPM_OPT_FLAGS -DNDEBUG $(getconf LFS_CFLAGS)"
+export CXXFLAGS="$RPM_OPT_FLAGS -DNDEBUG $(getconf LFS_CFLAGS)"
%if %{?_with_debug:1}%{!?_with_debug:0}
-cmake .. \
- -DYPREFIX=%{_prefix} \
- -DDOC_DIR=%{_docdir} \
- -DLIB_DIR=%{_lib} \
- -DCMAKE_BUILD_TYPE=RELWITHDEBINFO
+CMAKE_OPTS="-DCMAKE_BUILD_TYPE=RELWITHDEBINFO"
%else
+CMAKE_OPTS="-DCMAKE_BUILD_TYPE=RELEASE"
+%endif
+%endif
+
cmake .. \
-DYPREFIX=%{_prefix} \
-DDOC_DIR=%{_docdir} \
-DLIB_DIR=%{_lib} \
- -DCMAKE_BUILD_TYPE=RELEASE
-%endif
+ $CMAKE_OPTS
make %{?jobs:-j%jobs}
+%check
+cd build
+make test
+%if %{with coverage}
+# generate code coverage data
+make coverage
+%endif
+
%install
cd build
make install DESTDIR="$RPM_BUILD_ROOT"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libyui-3.4.1/src/FSize.cc new/libyui-3.4.2/src/FSize.cc
--- old/libyui-3.4.1/src/FSize.cc 2018-05-14 14:10:38.000000000 +0200
+++ new/libyui-3.4.2/src/FSize.cc 2018-07-31 09:50:54.000000000 +0200
@@ -1,5 +1,7 @@
/*
Copyright (C) 2000-2012 Novell, Inc
+ Copyright (C) 2018 SUSE LLC
+
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2.1 of the
@@ -25,14 +27,28 @@
/-*/
-#include
-#include
#include <iostream>
+#include <sstream>
#include "FSize.h"
+// arbitrary precision float for floating point division
+#include
+
+using boost::multiprecision::cpp_int;
+
+const cpp_int FSize::KB = 1024;
+const cpp_int FSize::MB = FSize::KB * 1024;
+const cpp_int FSize::GB = FSize::MB * 1024;
+const cpp_int FSize::TB = FSize::GB * 1024;
+const cpp_int FSize::PB = FSize::TB * 1024;
+const cpp_int FSize::EB = FSize::PB * 1024;
+const cpp_int FSize::ZB = FSize::EB * 1024;
+const cpp_int FSize::YB = FSize::ZB * 1024;
+
+
FSize::FSize( const std::string &sizeStr, const Unit unit_r )
- : _size( atoll( sizeStr.c_str() ) * factor( unit_r ) )
+ : _size( cpp_int(sizeStr) * factor( unit_r ) )
{
}
@@ -45,11 +61,11 @@
//
FSize & FSize::fillBlock( FSize blocksize_r )
{
- if ( _size && blocksize_r ) {
- long long diff = _size % blocksize_r;
+ if ( _size > 0 && cpp_int(blocksize_r) > 0) {
+ cpp_int diff = _size % cpp_int(blocksize_r);
if ( diff ) {
if ( _size > 0 )
- _size += blocksize_r;
+ _size += cpp_int(blocksize_r);
_size -= diff;
}
}
@@ -65,16 +81,24 @@
//
FSize::Unit FSize::bestUnit() const
{
- long long usize( _size < 0 ? -_size : _size );
+ cpp_int usize = abs(_size);
if ( usize < KB )
- return B;
+ return Unit::B;
if ( usize < MB )
- return K;
+ return Unit::K;
if ( usize < GB )
- return M;
+ return Unit::M;
if ( usize < TB )
- return G;
- return T;
+ return Unit::G;
+ if ( usize < PB )
+ return Unit::T;
+ if ( usize < EB )
+ return Unit::P;
+ if ( usize < ZB )
+ return Unit::E;
+ if ( usize < YB )
+ return Unit::Z;
+ return Unit::Y;
}
//
@@ -89,26 +113,36 @@
if ( prec == bestPrec ) {
switch ( unit_r )
{
- case T: prec = 3; break;
- case G: prec = 2; break;
- case M: prec = 1; break;
- case K: prec = 1; break;
- case B: prec = 0; break;
+ case Unit::Y: prec = 3; break;
+ case Unit::Z: prec = 3; break;
+ case Unit::E: prec = 3; break;
+ case Unit::P: prec = 3; break;
+ case Unit::T: prec = 3; break;
+ case Unit::G: prec = 2; break;
+ case Unit::M: prec = 1; break;
+ case Unit::K: prec = 1; break;
+ case Unit::B: prec = 0; break;
}
- } else if ( unit_r == B )
+} else if ( unit_r == Unit::B )
prec = 0; // doesn't make sense for Byte
- char buffer[80]; // should be long enough for any numeric sprintf()
- snprintf( buffer, sizeof( buffer ),
- "%*.*f",
- fw, prec, ( double( _size ) / factor( unit_r ) ) );
-
- std::string ret( buffer );
+ std::ostringstream str;
+ // set the precision and field width, use fixed notation (not the scientific Xe+Y)
+ str << std::setprecision(prec) << std::setfill(' ') << std::setw(fw) << std::fixed;
+
+ if (prec == 0)
+ // no decimal part required, we can use integer division,
+ // add one unit half for correct rounding
+ str << (_size + (factor( unit_r ) / 2))/ factor( unit_r );
+ else
+ // otherwise convert to boost floats
+ str << (boost::multiprecision::cpp_bin_float_50)( _size ) /
+ (boost::multiprecision::cpp_bin_float_50)(factor( unit_r ) );
if ( showunit )
- ret += std::string(" ") + unit( unit_r );
+ str << " " << unit( unit_r );
- return ret;
+ return str.str();
}
@@ -123,3 +157,15 @@
{
return form();
}
+
+std::ostream& operator<<(std::ostream &ostr, const FSize &fsize)
+{
+ ostr << fsize.asString();
+ return ostr;
+}
+
+std::ostream& operator<<(std::ostream &ostr, const FSize::Unit unit)
+{
+ ostr << FSize::unit(unit);
+ return ostr;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libyui-3.4.1/src/FSize.h new/libyui-3.4.2/src/FSize.h
--- old/libyui-3.4.1/src/FSize.h 2018-05-14 14:10:38.000000000 +0200
+++ new/libyui-3.4.2/src/FSize.h 2018-07-31 09:50:54.000000000 +0200
@@ -1,5 +1,6 @@
/*
Copyright (C) 2000-2012 Novell, Inc
+ Copyright (C) 2018 SUSE LLC
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2.1 of the
@@ -21,7 +22,7 @@
Author: Michael Andres
Maintainer: Michael Andres
- Purpose: Store and operate on (file/package/partition) sizes (long long).
+ Purpose: Store and operate on (file/package/partition) sizes.
/-*/
#ifndef _FSize_h_
@@ -30,45 +31,65 @@
#include <iosfwd>
#include <string>
+// arbitrary precision integer
+#include
+// generate additional operators via the boost templates
+#include
+
//
// CLASS NAME : FSize
//
/**
- * Store and operate on (file/package/partition) sizes (long long).
+ * Store and operate on (file/package/partition) sizes.
**/
-class FSize {
+class FSize :
+ // generate > / * + - <= => !== operators
+ boost::ordered_field_operators<FSize>,
+ // generate postfix ++ --
+ boost::unit_steppable<FSize>
+ {
public:
/**
* The Units
**/
- enum Unit { B = 0, K, M, G, T };
+ enum class Unit { B, K, M, G, T, P, E, Z, Y };
private:
/**
- * The size in Byte
+ * The size (in bytes)
+ * @see https://www.boost.org/doc/libs/release/libs/multiprecision/doc/html/index.ht...
**/
- long long _size;
+ boost::multiprecision::cpp_int _size;
public:
- static const long long KB = 1024;
- static const long long MB = 1024 * KB;
- static const long long GB = 1024 * MB;
- static const long long TB = 1024 * GB;
+ static const boost::multiprecision::cpp_int KB;
+ static const boost::multiprecision::cpp_int MB;
+ static const boost::multiprecision::cpp_int GB;
+ static const boost::multiprecision::cpp_int TB;
+ static const boost::multiprecision::cpp_int PB;
+ static const boost::multiprecision::cpp_int EB;
+ // these do not fit long long anymore!
+ static const boost::multiprecision::cpp_int ZB;
+ static const boost::multiprecision::cpp_int YB;
/**
- * Return ammount of Byte in Unit.
+ * Return ammount of bytes in Unit.
**/
- static long long factor( const Unit unit_r ) {
+ static boost::multiprecision::cpp_int factor( const Unit unit_r ) {
switch ( unit_r ) {
- case T: return TB;
- case G: return GB;
- case M: return MB;
- case K: return KB;
- case B: break;
+ case Unit::Y: return YB;
+ case Unit::Z: return ZB;
+ case Unit::E: return EB;
+ case Unit::P: return PB;
+ case Unit::T: return TB;
+ case Unit::G: return GB;
+ case Unit::M: return MB;
+ case Unit::K: return KB;
+ case Unit::B: break;
}
return 1;
}
@@ -78,11 +99,15 @@
**/
static const char * unit( const Unit unit_r ) {
switch ( unit_r ) {
- case T: return "TB";
- case G: return "GB";
- case M: return "MB";
- case K: return "kB";
- case B: break;
+ case Unit::Y: return "YiB";
+ case Unit::Z: return "ZiB";
+ case Unit::E: return "EiB";
+ case Unit::P: return "PiB";
+ case Unit::T: return "TiB";
+ case Unit::G: return "GiB";
+ case Unit::M: return "MiB";
+ case Unit::K: return "KiB";
+ case Unit::B: break;
}
return "B";
}
@@ -90,55 +115,71 @@
public:
/**
- * Construct from size in Byte.
+ * Construct from size in certain unit.
+ * E.g. <code>FSize( 1, FSize::Unit::K )<code> makes 1024 Byte.
**/
- FSize( const long long size_r = 0 )
- : _size( size_r )
+ FSize( const boost::multiprecision::cpp_int &size_r = 0, const Unit unit_r = Unit::B)
+ : _size( boost::multiprecision::cpp_int(size_r) * factor( unit_r ) )
{}
/**
- * Construct from size in certain unit.
- * E.g. <code>FSize( 1, FSize::K )<code> makes 1024 Byte.
+ * Construct from size in Byte.
+ * @param size_r the initial value
**/
- FSize( const long long size_r, const Unit unit_r )
- : _size( size_r * factor( unit_r ) )
+ FSize( double size_r )
+ : _size( size_r )
{}
/**
Construct from string containing a number in given unit.
+ * @param sizeStr input string - must contain *only* numbers
+ * @param unit_r optional unit, bytes by default
+ * @throws std::runtime_error if the string contains any non numeric characters,
+ * even a trailing white space!
*/
- FSize( const std::string &sizeStr, const Unit unit_r = B );
+ FSize( const std::string &sizeStr, const Unit unit_r = Unit::B );
/**
- * Conversion to long long
- **/
- operator long long() const { return _size; }
-
- FSize & operator+=( const long long rhs ) { _size += rhs; return *this; }
- FSize & operator-=( const long long rhs ) { _size -= rhs; return *this; }
- FSize & operator*=( const long long rhs ) { _size *= rhs; return *this; }
- FSize & operator/=( const long long rhs ) { _size /= rhs; return *this; }
-
- FSize & operator++(/*prefix*/) { _size += 1; return *this; }
- FSize & operator--(/*prefix*/) { _size -= 1; return *this; }
-
- FSize operator++(int/*postfix*/) { return _size++; }
- FSize operator--(int/*postfix*/) { return _size--; }
+ * Conversions to native data types - only explicit as it might overflow
+ * If the value is out of range then the behavior depends on the boost version
+ * - 1.67 - the min/max values for the corresponding type are returned
+ * - 1.66 - returns just the lower bits
+ **/
+ explicit operator long long() const { return static_cast<long long>(_size); }
+ explicit operator int() const { return static_cast<int>(_size); }
+ explicit operator double() const { return static_cast<double>(_size); }
+
+ operator boost::multiprecision::cpp_int() const { return _size; }
+ boost::multiprecision::cpp_int in_unit(const Unit unit_r) const { return _size / factor( unit_r ); }
+
+ // unary minus
+ FSize operator-() const { return FSize(-_size); }
+ FSize & operator+=( const FSize &rhs ) { _size += boost::multiprecision::cpp_int(rhs); return *this; }
+ FSize & operator-=( const FSize &rhs ) { _size -= boost::multiprecision::cpp_int(rhs); return *this; }
+ FSize & operator*=( const FSize &rhs ) { _size *= boost::multiprecision::cpp_int(rhs); return *this; }
+ FSize & operator/=( const FSize &rhs ) { _size /= boost::multiprecision::cpp_int(rhs); return *this; }
+
+ bool operator<( const FSize &rhs ) const { return _size < boost::multiprecision::cpp_int(rhs); }
+ bool operator==( const FSize &rhs ) const { return _size == boost::multiprecision::cpp_int(rhs); }
+
+ // ++operator (the prefix variant)
+ FSize & operator++() { _size += 1; return *this; }
+ // --operator (the prefix variant)
+ FSize & operator--() { _size -= 1; return *this; }
/**
* Adjust size to multiple of <code>blocksize_r</code>
**/
- FSize & fillBlock( FSize blocksize_r = KB );
+ FSize & fillBlock( FSize blocksize_r = boost::multiprecision::cpp_int(KB) );
/**
- * Return size adjusted to multiple of <code>blocksize_r</code>
+ * Return a new size adjusted to multiple of <code>blocksize_r</code>
**/
- FSize fullBlock( FSize blocksize_r = KB ) const { FSize ret( _size ); return ret.fillBlock( blocksize_r ); }
-
- /**
- * Return size in Unit ( not rounded )
- **/
- long long operator()( const Unit unit_r ) const { return _size / factor( unit_r ); }
+ FSize fullBlock( FSize blocksize_r = boost::multiprecision::cpp_int(KB) ) const
+ {
+ FSize ret( _size );
+ return ret.fillBlock( blocksize_r );
+ }
/**
* Return the best unit for string representation.
@@ -176,5 +217,8 @@
std::string asString() const;
};
+// stream operators
+std::ostream& operator<<(std::ostream &ostr, const FSize&);
+std::ostream& operator<<(std::ostream &ostr, const FSize::Unit);
#endif // _FSize_h_
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libyui-3.4.1/tests/CMakeLists.txt new/libyui-3.4.2/tests/CMakeLists.txt
--- old/libyui-3.4.1/tests/CMakeLists.txt 1970-01-01 01:00:00.000000000 +0100
+++ new/libyui-3.4.2/tests/CMakeLists.txt 2018-07-31 09:50:54.000000000 +0200
@@ -0,0 +1 @@
+PROCESS_TESTS()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libyui-3.4.1/tests/FSize_test.cc new/libyui-3.4.2/tests/FSize_test.cc
--- old/libyui-3.4.1/tests/FSize_test.cc 1970-01-01 01:00:00.000000000 +0100
+++ new/libyui-3.4.2/tests/FSize_test.cc 2018-07-31 09:50:54.000000000 +0200
@@ -0,0 +1,419 @@
+/*
+ Copyright (C) 2018 SUSE LLC
+
+ This library is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) version 3.0 of the License. This library
+ is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details. You should have received a copy of the GNU
+ Lesser General Public License along with this library; if not, write
+ to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+ Floor, Boston, MA 02110-1301 USA
+*/
+
+// This is an unit test for the FSize class
+
+#define BOOST_TEST_MODULE FSize_tests
+#include
+#include
+
+#include <limits>
+#include <sstream>
+
+#include "FSize.h"
+
+using boost::multiprecision::cpp_int;
+
+// decrease the log level to warnings
+struct LogWarnings {
+ // global initialization before running any test
+ void setup() {
+ boost::unit_test::unit_test_log.set_threshold_level( boost::unit_test::log_warnings );
+ }
+ // cleanup after all tests are finished
+ void teardown() { }
+};
+
+BOOST_TEST_GLOBAL_FIXTURE( LogWarnings );
+
+BOOST_AUTO_TEST_CASE( constructor )
+{
+ // check the default constructor
+ FSize fsize;
+ BOOST_CHECK_EQUAL( fsize, 0 );
+
+ // check an int parameter
+ FSize fsize_int(42);
+ BOOST_CHECK_EQUAL( fsize_int, 42 );
+
+ // check a long long parameter
+ FSize fsize_long(1LL << 40);
+ BOOST_CHECK_EQUAL( fsize_long, 1LL << 40);
+
+ // check a double parameter
+ FSize fsize_double(42.0);
+ BOOST_CHECK_EQUAL( fsize_double, 42.0);
+ // the decimal part is ignored
+ BOOST_CHECK_EQUAL( fsize_double, FSize(42.1));
+ BOOST_CHECK_EQUAL( fsize_double, FSize(42.5));
+ BOOST_CHECK_EQUAL( fsize_double, FSize(42.9));
+
+ // check negative number
+ FSize fsize_int_neg(-42);
+ BOOST_CHECK_EQUAL( fsize_int_neg, -42 );
+
+ // create with units
+ long long u = 1;
+ BOOST_CHECK_EQUAL( FSize(1, FSize::Unit::B), 1);
+ BOOST_CHECK_EQUAL( FSize(1, FSize::Unit::K), u *= 1024);
+ BOOST_CHECK_EQUAL( FSize(1, FSize::Unit::M), u *= 1024);
+ BOOST_CHECK_EQUAL( FSize(1, FSize::Unit::G), u *= 1024);
+ BOOST_CHECK_EQUAL( FSize(1, FSize::Unit::T), u *= 1024);
+ BOOST_CHECK_EQUAL( FSize(1, FSize::Unit::P), u *= 1024);
+ BOOST_CHECK_EQUAL( FSize(1, FSize::Unit::E), u *= 1024);
+ // too much for a long long...
+ BOOST_CHECK_EQUAL( FSize(1, FSize::Unit::Z), cpp_int(1) << 70);
+ BOOST_CHECK_EQUAL( FSize(1, FSize::Unit::Y), cpp_int(1) << 80);
+
+ BOOST_CHECK_EQUAL( FSize(128, FSize::Unit::K), 128 * 1024);
+ BOOST_CHECK_EQUAL( FSize(-128, FSize::Unit::K), -(128 * 1024));
+
+ // from string
+ BOOST_CHECK_EQUAL( FSize("128", FSize::Unit::K), 128 * 1024);
+ BOOST_CHECK_EQUAL( FSize("-128", FSize::Unit::K), -128 * 1024);
+ BOOST_CHECK_EQUAL( FSize("856", FSize::Unit::M), 856 * 1024 * 1024);
+
+ // throws std::runtime_error exception for invalid data!!
+ BOOST_CHECK_THROW( FSize("72.89", FSize::Unit::K), std::runtime_error);
+ BOOST_CHECK_THROW( FSize(" 72 ", FSize::Unit::K), std::runtime_error);
+ BOOST_CHECK_THROW( FSize("72asdf", FSize::Unit::K), std::runtime_error);
+}
+
+BOOST_AUTO_TEST_CASE( comparing_positive )
+{
+ FSize fsize(42);
+ BOOST_CHECK_EQUAL( fsize == 42, true );
+ BOOST_CHECK_EQUAL( fsize != 42, false );
+
+ BOOST_CHECK_EQUAL( fsize > 0, true );
+ BOOST_CHECK_EQUAL( fsize > 10, true );
+ BOOST_CHECK_EQUAL( fsize > 42, false );
+ BOOST_CHECK_EQUAL( fsize > -42, true );
+
+ BOOST_CHECK_EQUAL( fsize >= 0, true );
+ BOOST_CHECK_EQUAL( fsize >= 10, true );
+ BOOST_CHECK_EQUAL( fsize >= 42, true );
+ BOOST_CHECK_EQUAL( fsize >= -42, true );
+
+ BOOST_CHECK_EQUAL( fsize < 0, false );
+ BOOST_CHECK_EQUAL( fsize < 10, false );
+ BOOST_CHECK_EQUAL( fsize < 42, false );
+ BOOST_CHECK_EQUAL( fsize < -42, false );
+
+ BOOST_CHECK_EQUAL( fsize < 0, false );
+ BOOST_CHECK_EQUAL( fsize < 10, false );
+ BOOST_CHECK_EQUAL( fsize <= 42, true );
+ BOOST_CHECK_EQUAL( fsize <= -42, false );
+}
+
+BOOST_AUTO_TEST_CASE( comparing_negative )
+{
+ FSize fsize(-42);
+ BOOST_CHECK_EQUAL( fsize == -42, true );
+ BOOST_CHECK_EQUAL( fsize != -42, false );
+
+ BOOST_CHECK_EQUAL( fsize > 0, false );
+ BOOST_CHECK_EQUAL( fsize > 10, false );
+ BOOST_CHECK_EQUAL( fsize > -42, false );
+ BOOST_CHECK_EQUAL( fsize > -52, true );
+
+ BOOST_CHECK_EQUAL( fsize >= 0, false );
+ BOOST_CHECK_EQUAL( fsize >= 10, false );
+ BOOST_CHECK_EQUAL( fsize >= -42, true );
+ BOOST_CHECK_EQUAL( fsize >= -52, true );
+
+ BOOST_CHECK_EQUAL( fsize < 0, true );
+ BOOST_CHECK_EQUAL( fsize < 10, true );
+ BOOST_CHECK_EQUAL( fsize < 42, true );
+ BOOST_CHECK_EQUAL( fsize < -42, false );
+ BOOST_CHECK_EQUAL( fsize < -52, false );
+
+ BOOST_CHECK_EQUAL( fsize < 0, true );
+ BOOST_CHECK_EQUAL( fsize < 10, true );
+ BOOST_CHECK_EQUAL( fsize <= 42, true );
+ BOOST_CHECK_EQUAL( fsize <= -42, true );
+ BOOST_CHECK_EQUAL( fsize <= -52, false );
+}
+
+BOOST_AUTO_TEST_CASE( comparing_fsizes )
+{
+ FSize fsize(100);
+ FSize fsize_copy(fsize);
+ FSize fsize_double(100.0);
+ FSize fsize_negative(-100);
+ FSize fsize_different(200);
+
+ BOOST_CHECK_EQUAL( fsize, fsize_copy );
+ BOOST_CHECK_EQUAL( fsize, fsize_double );
+ BOOST_CHECK_NE( fsize, fsize_different );
+ BOOST_CHECK_NE( fsize, fsize_negative );
+
+ BOOST_CHECK_EQUAL( fsize < fsize_copy, false );
+ BOOST_CHECK_EQUAL( fsize > fsize_copy, false );
+ BOOST_CHECK_EQUAL( fsize <= fsize_copy, true );
+ BOOST_CHECK_EQUAL( fsize >= fsize_copy, true );
+ BOOST_CHECK_EQUAL( fsize < fsize_different, true );
+ BOOST_CHECK_EQUAL( fsize > fsize_different, false );
+ BOOST_CHECK_EQUAL( fsize <= fsize_different, true );
+ BOOST_CHECK_EQUAL( fsize >= fsize_different, false );
+}
+
+BOOST_AUTO_TEST_CASE( comparing_with_limits )
+{
+ // 2^1024
+ FSize fsize(cpp_int(1) << 1024);
+
+ // even bigger than the max long long
+ BOOST_CHECK(fsize > std::numeric_limits<long long>::max());
+ // even bigger than the max unsigned long long
+ BOOST_CHECK(fsize > std::numeric_limits<unsigned long long>::max());
+ // even bigger than the max double
+ BOOST_CHECK(fsize > std::numeric_limits<double>::max());
+
+ // compare with the negative limits
+ fsize *= -1;
+ // even lower than the min long long
+ BOOST_CHECK(fsize < std::numeric_limits<long long>::min());
+ // even lower than the min unsigned long long
+ BOOST_CHECK(fsize < std::numeric_limits<unsigned long long>::min());
+ // even lower than the min double
+ BOOST_CHECK(fsize < std::numeric_limits<double>::min());
+}
+
+BOOST_AUTO_TEST_CASE( operators_on_self )
+{
+ FSize fsize(42);
+
+ fsize += 42;
+ BOOST_CHECK(fsize == 84);
+ fsize -= 42;
+ BOOST_CHECK(fsize == 42);
+ fsize -= 42;
+ BOOST_CHECK(fsize == 0);
+ fsize -= 42;
+ BOOST_CHECK(fsize == -42);
+ fsize *= -1;
+ BOOST_CHECK(fsize == 42);
+ fsize *= 8;
+ BOOST_CHECK(fsize == 336);
+ fsize /= 6;
+ BOOST_CHECK(fsize == 56);
+
+ // check some bigger values, 10TiB
+ FSize fsize2(10, FSize::Unit::T);
+ // 10TiB / 10 => 1TiB
+ fsize2 /= 10;
+ BOOST_CHECK(fsize2 == FSize::TB);
+}
+
+BOOST_AUTO_TEST_CASE( operators )
+{
+ BOOST_CHECK_EQUAL(FSize(20) + FSize(22), 42);
+ BOOST_CHECK_EQUAL(FSize(64) - FSize(22), 42);
+ BOOST_CHECK_EQUAL(FSize(64) * FSize(4), 256);
+ BOOST_CHECK_EQUAL(FSize(1024) / FSize(8), 128);
+
+ BOOST_CHECK_EQUAL(20 + FSize(22), 42);
+ BOOST_CHECK_EQUAL(64 - FSize(22), 42);
+ BOOST_CHECK_EQUAL(64 * FSize(4), 256);
+ BOOST_CHECK_EQUAL(1024 / FSize(8), 128);
+
+ BOOST_CHECK_EQUAL(FSize(20) + 22, 42);
+ BOOST_CHECK_EQUAL(FSize(64) - 22, 42);
+ BOOST_CHECK_EQUAL(FSize(64) * 4, 256);
+ BOOST_CHECK_EQUAL(FSize(1024) / 8, 128);
+
+ // unary minus
+ BOOST_CHECK_EQUAL(-FSize(120), -120);
+
+ // increment/decrement
+ FSize test(120);
+ // post increment
+ BOOST_CHECK_EQUAL(test++, 120);
+ // changed
+ BOOST_CHECK_EQUAL(test, 121);
+ // pre increment
+ BOOST_CHECK_EQUAL(++test, 122);
+ // not changed
+ BOOST_CHECK_EQUAL(test, 122);
+
+ // post decrement
+ BOOST_CHECK_EQUAL(test--, 122);
+ // changed
+ BOOST_CHECK_EQUAL(test, 121);
+ // pre decrement
+ BOOST_CHECK_EQUAL(--test, 120);
+ // not changed
+ BOOST_CHECK_EQUAL(test, 120);
+}
+
+BOOST_AUTO_TEST_CASE( fillBlock )
+{
+ BOOST_CHECK_EQUAL(FSize(0).fillBlock(), 0);
+ BOOST_CHECK_EQUAL(FSize(1).fillBlock(), 1024);
+ BOOST_CHECK_EQUAL(FSize(4000).fillBlock(), 4096);
+ BOOST_CHECK_EQUAL(FSize(42 * 1024).fillBlock(), 42 * 1024);
+ BOOST_CHECK_EQUAL(FSize(42 * 1024).fillBlock(32 * 1024), 65536);
+
+ // fillBlock() changes the object
+ int value = 42 * 1024; // 42KiB
+ FSize fsize(value);
+ BOOST_CHECK_EQUAL(fsize.fillBlock(32 * 1024), 65536);
+ // not equal to the original size
+ BOOST_CHECK_NE(fsize, value);
+}
+
+BOOST_AUTO_TEST_CASE( fullBlock )
+{
+ BOOST_CHECK_EQUAL(FSize(0).fullBlock(), 0);
+ BOOST_CHECK_EQUAL(FSize(1).fullBlock(), 1024);
+ BOOST_CHECK_EQUAL(FSize(4000).fullBlock(), 4096);
+ BOOST_CHECK_EQUAL(FSize(42 * 1024).fullBlock(), 42 * 1024);
+ BOOST_CHECK_EQUAL(FSize(42 * 1024).fullBlock(32 * 1024), 65536);
+
+ // fullBlock() creates a new object
+ int value = 42 * 1024; // 42KiB
+ FSize fsize(value);
+ BOOST_CHECK_EQUAL(fsize.fullBlock(32 * 1024), 65536);
+ // not changed
+ BOOST_CHECK_EQUAL(fsize, value);
+}
+
+BOOST_AUTO_TEST_CASE( bestUnit )
+{
+ BOOST_CHECK_EQUAL(FSize(0).bestUnit(), FSize::Unit::B);
+ BOOST_CHECK_EQUAL(FSize(999).bestUnit(), FSize::Unit::B);
+ BOOST_CHECK_EQUAL(FSize(1023).bestUnit(), FSize::Unit::B);
+ BOOST_CHECK_EQUAL(FSize(1024).bestUnit(), FSize::Unit::K);
+
+ BOOST_CHECK_EQUAL(FSize(1LL << 20).bestUnit(), FSize::Unit::M);
+ BOOST_CHECK_EQUAL(FSize(1LL << 30).bestUnit(), FSize::Unit::G);
+ BOOST_CHECK_EQUAL(FSize(1LL << 40).bestUnit(), FSize::Unit::T);
+ BOOST_CHECK_EQUAL(FSize(1LL << 50).bestUnit(), FSize::Unit::P);
+ BOOST_CHECK_EQUAL(FSize(1LL << 60).bestUnit(), FSize::Unit::E);
+ BOOST_CHECK_EQUAL(FSize(cpp_int(1) << 70).bestUnit(), FSize::Unit::Z);
+ BOOST_CHECK_EQUAL(FSize(cpp_int(1) << 80).bestUnit(), FSize::Unit::Y);
+}
+
+BOOST_AUTO_TEST_CASE( unit )
+{
+ BOOST_CHECK_EQUAL(FSize::unit(FSize::Unit::B), "B");
+ BOOST_CHECK_EQUAL(FSize::unit(FSize::Unit::K), "KiB");
+ BOOST_CHECK_EQUAL(FSize::unit(FSize::Unit::M), "MiB");
+ BOOST_CHECK_EQUAL(FSize::unit(FSize::Unit::G), "GiB");
+ BOOST_CHECK_EQUAL(FSize::unit(FSize::Unit::T), "TiB");
+ BOOST_CHECK_EQUAL(FSize::unit(FSize::Unit::P), "PiB");
+ BOOST_CHECK_EQUAL(FSize::unit(FSize::Unit::E), "EiB");
+ BOOST_CHECK_EQUAL(FSize::unit(FSize::Unit::Z), "ZiB");
+ BOOST_CHECK_EQUAL(FSize::unit(FSize::Unit::Y), "YiB");
+}
+
+BOOST_AUTO_TEST_CASE( form )
+{
+ BOOST_CHECK_EQUAL(FSize(0).form(), "0 B");
+ BOOST_CHECK_EQUAL(FSize(1).form(), "1 B");
+ BOOST_CHECK_EQUAL(FSize(1024).form(), "1.0 KiB");
+ BOOST_CHECK_EQUAL(FSize(-1024).form(), "-1.0 KiB");
+ BOOST_CHECK_EQUAL(FSize(FSize::MB).form(), "1.0 MiB");
+ BOOST_CHECK_EQUAL(FSize(123456789).form(), "117.7 MiB");
+ // requested unit
+ BOOST_CHECK_EQUAL(FSize(123456789).form(FSize::Unit::K), "120563.3 KiB");
+ BOOST_CHECK_EQUAL(FSize(123456789).form(FSize::Unit::M), "117.7 MiB");
+ BOOST_CHECK_EQUAL(FSize(123456789).form(FSize::Unit::G), "0.11 GiB");
+ // too small for the required unit
+ BOOST_CHECK_EQUAL(FSize(123456789).form(FSize::Unit::T), "0.000 TiB");
+ BOOST_CHECK_EQUAL(FSize(123456789).form(FSize::Unit::P), "0.000 PiB");
+ BOOST_CHECK_EQUAL(FSize(123456789).form(FSize::Unit::E), "0.000 EiB");
+ BOOST_CHECK_EQUAL(FSize(123456789).form(FSize::Unit::Z), "0.000 ZiB");
+ BOOST_CHECK_EQUAL(FSize(123456789).form(FSize::Unit::Y), "0.000 YiB");
+
+ // field width
+ BOOST_CHECK_EQUAL(FSize(123456789).form(10), " 117.7 MiB");
+ // the width parameter does NOT include the units!
+ BOOST_CHECK_EQUAL(FSize(123456789).form(10).length(), 14);
+ // does not cut numbers for longer strings
+ BOOST_CHECK_EQUAL(FSize(123456789).form(FSize::Unit::K, 5), "120563.3 KiB");
+
+ // precision
+ BOOST_CHECK_EQUAL(FSize(123456789).form(0, 3), "117.738 MiB");
+ BOOST_CHECK_EQUAL(FSize(123456789).form(0, 0), "118 MiB");
+ BOOST_CHECK_EQUAL(FSize(123456789).form(FSize::Unit::K, 0, 3), "120563.271 KiB");
+ BOOST_CHECK_EQUAL(FSize(123456789).form(FSize::Unit::K, 0, 0), "120563 KiB");
+ // precision for bytes is ignored
+ BOOST_CHECK_EQUAL(FSize(1234).form(FSize::Unit::B, 0, 3), "1234 B");
+
+ // without units
+ BOOST_CHECK_EQUAL(FSize(123456789).form(0, 3, false), "117.738");
+ BOOST_CHECK_EQUAL(FSize(123456789).form(0, 0, false), "118");
+ BOOST_CHECK_EQUAL(FSize(123456789).form(FSize::Unit::K, 0, 3, false), "120563.271");
+ BOOST_CHECK_EQUAL(FSize(123456789).form(FSize::Unit::K, 0, 0, false), "120563");
+}
+
+BOOST_AUTO_TEST_CASE( as_string )
+{
+ // the same behavior like form(), test just few examples
+ BOOST_CHECK_EQUAL(FSize(0).asString(), "0 B");
+ BOOST_CHECK_EQUAL(FSize(1).asString(), "1 B");
+ BOOST_CHECK_EQUAL(FSize(1024).asString(), "1.0 KiB");
+ BOOST_CHECK_EQUAL(FSize(-1024).asString(), "-1.0 KiB");
+ BOOST_CHECK_EQUAL(FSize(123456789).asString(), "117.7 MiB");
+}
+
+template<class T> std::string to_stream(const T& object)
+{
+ std::ostringstream str;
+
+ str << object;
+ return str.str();
+}
+
+BOOST_AUTO_TEST_CASE( output_operator )
+{
+ BOOST_CHECK_EQUAL(to_stream(FSize(0)), "0 B");
+ BOOST_CHECK_EQUAL(to_stream(FSize(1)), "1 B");
+ BOOST_CHECK_EQUAL(to_stream(FSize(1024)), "1.0 KiB");
+ BOOST_CHECK_EQUAL(to_stream(FSize(1024)), "1.0 KiB");
+ BOOST_CHECK_EQUAL(to_stream(FSize(123456789)), "117.7 MiB");
+
+ BOOST_CHECK_EQUAL(to_stream(FSize::Unit::B), "B");
+ BOOST_CHECK_EQUAL(to_stream(FSize::Unit::K), "KiB");
+ BOOST_CHECK_EQUAL(to_stream(FSize::Unit::M), "MiB");
+ BOOST_CHECK_EQUAL(to_stream(FSize::Unit::G), "GiB");
+ BOOST_CHECK_EQUAL(to_stream(FSize::Unit::T), "TiB");
+ BOOST_CHECK_EQUAL(to_stream(FSize::Unit::P), "PiB");
+ BOOST_CHECK_EQUAL(to_stream(FSize::Unit::E), "EiB");
+ BOOST_CHECK_EQUAL(to_stream(FSize::Unit::Z), "ZiB");
+ BOOST_CHECK_EQUAL(to_stream(FSize::Unit::Y), "YiB");
+}
+
+BOOST_AUTO_TEST_CASE( long_long_conversion )
+{
+ if (BOOST_VERSION >= 106700)
+ {
+ // Boost 1.67 returns min/max values for the values out of range
+ // https://www.boost.org/users/history/version_1_67_0.html
+ BOOST_CHECK_EQUAL((long long)(FSize::ZB), std::numeric_limits<long long>::max());
+ BOOST_CHECK_EQUAL((long long)(-FSize::YB), std::numeric_limits<long long>::min());
+ }
+ else
+ {
+ // the cpp_int convertion is buggy in older boost
+ // the older Boost (at least the 1.66 version) returns just the lower bits
+ // in that case just print a warning and continue
+ BOOST_WARN_EQUAL((long long)(FSize::ZB), std::numeric_limits<long long>::max());
+ BOOST_WARN_EQUAL((long long)(-FSize::YB), std::numeric_limits<long long>::min());
+ }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libyui-3.4.1/tests/README.md new/libyui-3.4.2/tests/README.md
--- old/libyui-3.4.1/tests/README.md 1970-01-01 01:00:00.000000000 +0100
+++ new/libyui-3.4.2/tests/README.md 2018-07-31 09:50:54.000000000 +0200
@@ -0,0 +1,36 @@
+
+# Unit Tests
+
+This directory contains unit tests.
+
+The unit tests are enabled by default, if you want to disable them (not
+recommended!) then use the `-DENABLE_TESTS=OFF` cmake option.
+
+
+## Writing Tests
+
+- The test files should end with `_test.cc` suffix.
+- Use the boost test framework, see the [documentation](
+https://www.boost.org/doc/libs/release/libs/test/doc/html/index.html).
+
+
+## Running the Tests
+
+Run `make test`. If some some test fails and you need to get more details
+then directly run the test binary from `build/tests` directory, it will print
+the details on the console.
+
+
+## Code Coverage
+
+The code coverage reporting can be enabled using the `-DENABLE_CODE_COVERAGE=ON`
+cmake option or using the `make -f Makefile.cvs COVERAGE=1` initial call.
+The `lcov` package needs to be installed.
+
+To print the code coverage run `make`, `make test` and `make coverage`.
+There is an additional all-in-one target which build the sources, runs the tests
+and prints the code coverage - simply run `make tests`.
+
+The code coverage summary will be displayed on the console. If you need more
+details (e.g. which lines are covered) then open the `coverage/index.html`
+file in a web browser.