Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package libHX for openSUSE:Factory checked in at 2022-03-16 21:30:33 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libHX (Old) and /work/SRC/openSUSE:Factory/.libHX.new.25692 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libHX" Wed Mar 16 21:30:33 2022 rev:65 rq:962119 version:4.4 Changes: -------- --- /work/SRC/openSUSE:Factory/libHX/libHX.changes 2021-10-20 20:24:30.293386245 +0200 +++ /work/SRC/openSUSE:Factory/.libHX.new.25692/libHX.changes 2022-03-16 21:30:44.483410682 +0100 @@ -1,0 +2,15 @@ +Tue Mar 15 13:10:55 UTC 2022 - Jan Engelhardt <jeng...@inai.de> + +- Update to release 4.4 + * Build fixes for mingw environments. + +------------------------------------------------------------------- +Mon Mar 14 17:16:20 UTC 2022 - Jan Engelhardt <jeng...@inai.de> + +- Update to release 4.3 + * string: New functions ``HX_strtoull_sec``, + ``HX_unit_seconds`` for converting between second-based time + durations and human-readable durations like 129600 <-> 1d12h. + * io: New function ``HX_sendfile``. + +------------------------------------------------------------------- Old: ---- libHX-4.2.tar.asc libHX-4.2.tar.xz New: ---- libHX-4.4.tar.asc libHX-4.4.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libHX.spec ++++++ --- /var/tmp/diff_new_pack.j21peP/_old 2022-03-16 21:30:45.179411210 +0100 +++ /var/tmp/diff_new_pack.j21peP/_new 2022-03-16 21:30:45.187411215 +0100 @@ -1,7 +1,7 @@ # # spec file for package libHX # -# Copyright (c) 2021 SUSE LLC +# Copyright (c) 2022 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -18,7 +18,7 @@ Name: libHX %define lname libHX32 -Version: 4.2 +Version: 4.4 Release: 0 Summary: Collection of routines for C and C++ programming License: LGPL-2.1-or-later ++++++ libHX-4.2.tar.xz -> libHX-4.4.tar.xz ++++++ ++++ 4392 lines of diff (skipped) ++++ retrying with extended exclude list diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libHX-4.2/build-aux/ar-lib new/libHX-4.4/build-aux/ar-lib --- old/libHX-4.2/build-aux/ar-lib 2021-10-17 15:37:09.995321077 +0200 +++ new/libHX-4.4/build-aux/ar-lib 2022-03-15 14:10:29.891707723 +0100 @@ -4,7 +4,7 @@ me=ar-lib scriptversion=2019-07-04.01; # UTC -# Copyright (C) 2010-2020 Free Software Foundation, Inc. +# Copyright (C) 2010-2021 Free Software Foundation, Inc. # Written by Peter Rosin <p...@lysator.liu.se>. # # This program is free software; you can redistribute it and/or modify diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libHX-4.2/build-aux/compile new/libHX-4.4/build-aux/compile --- old/libHX-4.2/build-aux/compile 2021-10-17 15:37:09.999321087 +0200 +++ new/libHX-4.4/build-aux/compile 2022-03-15 14:10:29.891707723 +0100 @@ -3,7 +3,7 @@ scriptversion=2018-03-07.03; # UTC -# Copyright (C) 1999-2020 Free Software Foundation, Inc. +# Copyright (C) 1999-2021 Free Software Foundation, Inc. # Written by Tom Tromey <tro...@cygnus.com>. # # This program is free software; you can redistribute it and/or modify diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libHX-4.2/build-aux/missing new/libHX-4.4/build-aux/missing --- old/libHX-4.2/build-aux/missing 2021-10-17 15:37:10.011321122 +0200 +++ new/libHX-4.4/build-aux/missing 2022-03-15 14:10:29.899707723 +0100 @@ -3,7 +3,7 @@ scriptversion=2018-03-07.03; # UTC -# Copyright (C) 1996-2020 Free Software Foundation, Inc. +# Copyright (C) 1996-2021 Free Software Foundation, Inc. # Originally written by Fran,cois Pinard <pin...@iro.umontreal.ca>, 1996. # This program is free software; you can redistribute it and/or modify diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libHX-4.2/build-aux/test-driver new/libHX-4.4/build-aux/test-driver --- old/libHX-4.2/build-aux/test-driver 2021-10-17 15:37:10.199321676 +0200 +++ new/libHX-4.4/build-aux/test-driver 2022-03-15 14:10:29.963707726 +0100 @@ -3,7 +3,7 @@ scriptversion=2018-03-07.03; # UTC -# Copyright (C) 2011-2020 Free Software Foundation, Inc. +# Copyright (C) 2011-2021 Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -110,8 +110,11 @@ trap "st=141; $do_exit" 13 trap "st=143; $do_exit" 15 -# Test script is run here. -"$@" >$log_file 2>&1 +# Test script is run here. We create the file first, then append to it, +# to ameliorate tests themselves also writing to the log file. Our tests +# don't, but others can (automake bug#35762). +: >"$log_file" +"$@" >>"$log_file" 2>&1 estatus=$? if test $enable_hard_errors = no && test $estatus -eq 99; then @@ -133,7 +136,7 @@ # know whether the test passed or failed simply by looking at the '.log' # file, without the need of also peaking into the corresponding '.trs' # file (automake bug#11814). -echo "$res $test_name (exit status: $estatus)" >>$log_file +echo "$res $test_name (exit status: $estatus)" >>"$log_file" # Report outcome to console. echo "${col}${res}${std}: $test_name" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libHX-4.2/configure.ac new/libHX-4.4/configure.ac --- old/libHX-4.2/configure.ac 2021-10-17 15:36:53.000000000 +0200 +++ new/libHX-4.4/configure.ac 2022-03-15 14:09:54.000000000 +0100 @@ -1,4 +1,4 @@ -AC_INIT([libHX], [4.2]) +AC_INIT([libHX], [4.4]) AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_MACRO_DIR([m4]) @@ -14,6 +14,13 @@ AC_LIBTOOL_DLOPEN AM_PROG_LIBTOOL +saved_CXXFLAGS="$CXXFLAGS" +regular_CPPFLAGS="-D_FILE_OFFSET_BITS=64 -D_REENTRANT" +regular_CFLAGS="-Wall -Waggregate-return -Wmissing-declarations \ + -Wmissing-prototypes -Wredundant-decls -Wshadow -Wstrict-prototypes \ + -Wformat=2 -pipe $visibility_CFLAGS" +regular_CXXFLAGS="-Wall -Wno-pointer-arith -Wredundant-decls -pipe \ + $visibility_CFLAGS" # # Check whether there really is a C++ compiler. # It is not mandatory to compile libHX, but we want to know. @@ -22,6 +29,21 @@ AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([], [return 0;])], [ac_cv_cxx=yes], [ac_cv_cxx=no]) +AC_MSG_CHECKING([available C++ standard]) +cxxmode="" +for i in "c++20" "c++17"; do + AS_IF([test "$i" = "c++20" && test -n "$COVERITY"], [continue]) + CXXFLAGS="$saved_CXXFLAGS -std=$i" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([])], [cxxmode="$i"]) + AS_IF([test -n "$cxxmode"], [break]) +done +CXXFLAGS="$saved_CXXFLAGS" +AS_IF([test -n "$cxxmode"], [ + regular_CXXFLAGS="$regular_CXXFLAGS -std=$cxxmode" + AC_MSG_RESULT([$cxxmode]) +], [ + AC_MSG_RESULT([none]) +]) AC_LANG_POP([C++]) AM_CONDITIONAL([HAVE_CXX], [test "$ac_cv_cxx" = yes]) @@ -107,12 +129,6 @@ AC_CHECK_FUNCS([getegid geteuid getpid getppid]) AC_CHECK_FUNCS([initgroups setgid]) -regular_CPPFLAGS="-D_FILE_OFFSET_BITS=64 -D_REENTRANT" -regular_CFLAGS="-Wall -Waggregate-return -Wmissing-declarations \ - -Wmissing-prototypes -Wredundant-decls -Wshadow -Wstrict-prototypes \ - -Wformat=2 -pipe $visibility_CFLAGS" -regular_CXXFLAGS="-Wall -Wno-pointer-arith -Wredundant-decls -pipe \ - $visibility_CFLAGS"; AC_SUBST([regular_CPPFLAGS]) AC_SUBST([regular_CFLAGS]) AC_SUBST([regular_CXXFLAGS]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libHX-4.2/doc/api.rst new/libHX-4.4/doc/api.rst --- old/libHX-4.2/doc/api.rst 2021-10-17 15:36:53.000000000 +0200 +++ new/libHX-4.4/doc/api.rst 2022-03-15 14:09:54.000000000 +0100 @@ -9,6 +9,8 @@ ====== ====== ====== ======================================== RMV MinVer FirstA Name ====== ====== ====== ======================================== +4.3 4.3 4.3 HX_unit_seconds +4.3 4.3 4.3 HX_strtoull_sec 4.2 4.2 4.2 HX_unit_size 4.2 4.2 4.2 HX_unit_size_cu 4.2 4.2 4.2 HX_strtod_unit diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libHX-4.2/doc/changelog.rst new/libHX-4.4/doc/changelog.rst --- old/libHX-4.2/doc/changelog.rst 2021-10-17 15:36:53.000000000 +0200 +++ new/libHX-4.4/doc/changelog.rst 2022-03-15 14:09:54.000000000 +0100 @@ -1,3 +1,23 @@ +v4.4 (2022-03-15) +================= + +Fixes: + +* Build fixes for the mingw environment. + + +v4.3 (2022-03-14) +================= + +Enhancements: + +* string: New functions ``HX_strtoull_sec``, ``HX_unit_seconds`` for converting + between second-based time durations and human-readable durations like + 129600 <-> 1d12h. +* io: New function ``HX_sendfile``. +* io: raise buffer size for ``HX_copy_file`` from 1 kiB to 64 kiB + + v4.2 (2021-10-17) ================= diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libHX-4.2/doc/files_and_dirs.rst new/libHX-4.4/doc/files_and_dirs.rst --- old/libHX-4.2/doc/files_and_dirs.rst 2021-10-17 15:36:53.000000000 +0200 +++ new/libHX-4.4/doc/files_and_dirs.rst 2022-03-15 14:09:54.000000000 +0100 @@ -178,9 +178,13 @@ ssize_t HXio_fullread(int fd, void *buf, size_t size, unsigned int flags); ssize_t HXio_fullwrite(int fd, const void *buf, size_t size, unsigned int flags); + ssize_t HX_sendfile(int dst, int src, size_t count); Since plain ``read``(2) and ``write``(2) may process only part of the buffer????? even more likely so with sockets?????, libHX provides two functions that calls these in a loop to retry said operations until the full amount has been processed. Since read and write can also be used with socket file descriptors, so can these. + +``HX_sendfile`` wraps ``sendfile``(2) for the same reason; in addition, it +falls back to a read-write loop on platforms which do not offer sendfile. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libHX-4.2/doc/shconfig.rst new/libHX-4.4/doc/shconfig.rst --- old/libHX-4.2/doc/shconfig.rst 2021-10-17 15:36:53.000000000 +0200 +++ new/libHX-4.4/doc/shconfig.rst 2022-03-15 14:09:54.000000000 +0100 @@ -103,7 +103,7 @@ ----------------- This particular example reads from the file in the home directory first (if it -exists), but stops after it has been successfull, so any subsequent locations +exists), but stops after it has been successful, so any subsequent locations listed in the paths variable are not read. This has the effect that the file from the home directory has the highest priority too like in the previous example, but without any keys from the system files. Note the ``SHCONF_ONE`` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libHX-4.2/doc/string_ops.rst new/libHX-4.4/doc/string_ops.rst --- old/libHX-4.2/doc/string_ops.rst 2021-10-17 15:36:53.000000000 +0200 +++ new/libHX-4.4/doc/string_ops.rst 2022-03-15 14:09:54.000000000 +0100 @@ -361,8 +361,8 @@ char *HX_unit_size(char *out, size_t outsize, unsigned long long number, unsigned int divisor, unsigned int cutoff); - char *HX_unit_size_p90(char *out, size_t outsize, - unsigned long long number, unsigned int divisor); + char *HX_unit_size_cu(char *out, size_t outsize, + unsigned long long number, unsigned int divisor); ``HX_unit_size`` takes an arbitrary number and and produces a more readily-readable shortened (string) representation with a unit suffix. It does @@ -433,6 +433,36 @@ unsigned long long bytes = HX_strtoull_unit("1.5G", NULL, 1024); +Conversion from/to human-readable durations with units +====================================================== + +.. code-block:: c + + #include <libHX/string.h> + + unsigned long long HX_strtoull_sec(const char *s, char **end); + char *HX_unit_seconds(char *out, size_t outsize, + unsigned long long seconds, + unsigned int flags); + +``HX_strtoull_sec`` converts a time duration with units, such as ``"15min30s"`` +into an all-seconds value. The recognized unit strings are: ``years``, +``year``, ``y``, ``months``, ``month``, ``days``, ``day``, ``d``, ``hours``, +``hour``, ``h``, ``minutes``, ``minute``, ``min``, ``seconds``, ``second``, +``s`` and the empty string (for seconds). When parsing stops at any point, +``*end`` is set to the location, similar to how the ``strtoull`` C function +would. + +One year is defined to be 365.25 days of 86400 seconds; one month is defined to +be 1/12 such a year. This is consistent with the units employed by systemd. + +``HX_unit_seconds`` is the reverse and transforms the duration given by +``seconds`` into a string representation broken into days, hours, minutes, and +remaining seconds as appropriate. By default, only the d/h/min/s units are +emitted. The ``flags`` argument specifies if any other units should be emitted; +``HXUNIT_YEARS``, ``HXUNIT_MONTHS`` and ``HXUNIT_WEEKS`` are available. + + Examples ======== diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libHX-4.2/include/libHX/defs.h new/libHX-4.4/include/libHX/defs.h --- old/libHX-4.2/include/libHX/defs.h 2021-10-17 15:36:53.000000000 +0200 +++ new/libHX-4.4/include/libHX/defs.h 2022-03-15 14:09:54.000000000 +0100 @@ -10,8 +10,8 @@ # endif # ifndef containerof # include <cstddef> -# define containerof(var, type, member) reinterpret_cast<type *>( \ - reinterpret_cast<char *>(var) - offsetof(type, member)) +# include <type_traits> +# define containerof(var, T, member) reinterpret_cast<std::conditional<std::is_const<std::remove_pointer<decltype(var)>::type>::value, std::add_const<T>::type, T>::type *>(reinterpret_cast<std::conditional<std::is_const<std::remove_pointer<decltype(var)>::type>::value, const char, char>::type *>(var) - offsetof(T, member)) # endif # ifndef static_cast # define static_cast(T, x) static_cast<T>(x) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libHX-4.2/include/libHX/io.h new/libHX-4.4/include/libHX/io.h --- old/libHX-4.2/include/libHX/io.h 2021-10-17 15:36:53.000000000 +0200 +++ new/libHX-4.4/include/libHX/io.h 2022-03-15 14:09:54.000000000 +0100 @@ -35,6 +35,7 @@ extern int HX_readlink(hxmc_t **, const char *); extern int HX_realpath(hxmc_t **, const char *, unsigned int); extern int HX_rrmdir(const char *); +extern ssize_t HX_sendfile(int dst, int src, size_t count); extern char *HX_slurp_fd(int fd, size_t *outsize); extern char *HX_slurp_file(const char *file, size_t *outsize); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libHX-4.2/include/libHX/misc.h new/libHX-4.4/include/libHX/misc.h --- old/libHX-4.2/include/libHX/misc.h 2021-10-17 15:36:53.000000000 +0200 +++ new/libHX-4.4/include/libHX/misc.h 2022-03-15 14:09:54.000000000 +0100 @@ -35,11 +35,11 @@ #define HX_TIMESPEC_FMT "%ld.%09ld" #define HX_TIMEVAL_FMT "%ld.%06ld" #ifdef __cplusplus -# define HX_TIMESPEC_EXP(p) static_cast<long>((p)->tv_sec), (p)->tv_nsec -# define HX_TIMEVAL_EXP(p) static_cast<long>((p)->tv_sec), (p)->tv_usec +# define HX_TIMESPEC_EXP(p) static_cast<long>((p)->tv_sec), static_cast<long>((p)->tv_nsec) +# define HX_TIMEVAL_EXP(p) static_cast<long>((p)->tv_sec), static_cast<long>((p)->tv_usec) #else -# define HX_TIMESPEC_EXP(p) static_cast(long, (p)->tv_sec), (p)->tv_nsec -# define HX_TIMEVAL_EXP(p) static_cast(long, (p)->tv_sec), (p)->tv_usec +# define HX_TIMESPEC_EXP(p) static_cast(long, (p)->tv_sec), static_cast(long, (p)->tv_nsec) +# define HX_TIMEVAL_EXP(p) static_cast(long, (p)->tv_sec), static_cast(long, (p)->tv_usec) #endif struct stat; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libHX-4.2/include/libHX/option.h new/libHX-4.4/include/libHX/option.h --- old/libHX-4.2/include/libHX/option.h 2021-10-17 15:36:53.000000000 +0200 +++ new/libHX-4.4/include/libHX/option.h 2022-03-15 14:09:54.000000000 +0100 @@ -77,7 +77,7 @@ * Type expected of struct HXoption.ptr is given in (). * HX_getopt (o) and HXformat_* (f) support different sets, marked with []. */ -enum HX_option_type { +enum { HXTYPE_NONE = 0, HXTYPE_VAL, HXTYPE_SVAL, @@ -110,7 +110,6 @@ HXTYPE_XSNTMARK, HXTYPE_XHELP, /* 30 */ HXTYPE_SIZE_T, -}; /** * Extra flags to be OR'ed into struct HXoption.type. @@ -125,7 +124,6 @@ * %HXOPT_AND: AND *ptr by argument * %HXOPT_XOR: XOR *ptr by argument */ -enum { HXOPT_OPTIONAL = 1 << 6, HXOPT_INC = 1 << 7, HXOPT_DEC = 1 << 8, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libHX-4.2/include/libHX/string.h new/libHX-4.4/include/libHX/string.h --- old/libHX-4.2/include/libHX/string.h 2021-10-17 15:36:53.000000000 +0200 +++ new/libHX-4.4/include/libHX/string.h 2022-03-15 14:09:54.000000000 +0100 @@ -31,6 +31,12 @@ _HXQUOTE_MAX, }; +enum { + HXUNIT_YEARS = 0x1U, + HXUNIT_MONTHS = 0x2U, + HXUNIT_WEEKS = 0x4U, +}; + #ifndef __libhx_internal_hxmc_t_defined #define __libhx_internal_hxmc_t_defined 1 typedef char hxmc_t; @@ -94,6 +100,8 @@ extern unsigned long long HX_strtoull_unit(const char *, char **, unsigned int exponent); extern char *HX_unit_size(char *out, size_t bufsize, unsigned long long size, unsigned int divisor, unsigned int cutoff); extern char *HX_unit_size_cu(char *out, size_t bufsize, unsigned long long size, unsigned int divisor); +extern unsigned long long HX_strtoull_sec(const char *s, char **); +extern char *HX_unit_seconds(char *out, size_t bufsize, unsigned long long seconds, unsigned int flags); static __inline__ void *HX_memdup(const void *buf, size_t len) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libHX-4.2/src/Makefile.am new/libHX-4.4/src/Makefile.am --- old/libHX-4.2/src/Makefile.am 2021-10-17 15:36:53.000000000 +0200 +++ new/libHX-4.4/src/Makefile.am 2022-03-15 14:09:54.000000000 +0100 @@ -13,7 +13,7 @@ mc.c misc.c opt.c proc.c \ rand.c socket.c string.c time.c libHX_la_LIBADD = ${libdl_LIBS} -lm ${libpthread_LIBS} ${librt_LIBS} -libHX_la_LDFLAGS = -no-undefined -version-info 34:0:2 +libHX_la_LDFLAGS = -no-undefined -version-info 35:0:3 if WITH_GNU_LD libHX_la_LDFLAGS += -Wl,--version-script=${srcdir}/libHX.map endif @@ -21,6 +21,7 @@ if MINGW32 libHX_la_SOURCES += ux-file.c ux-mmap.c +libHX_la_LIBADD += -lws2_32 endif libHX_rtcheck_la_SOURCES = rtcheck.c @@ -32,7 +33,7 @@ EXTRA_DIST = internal.h map_int.h libHX.map -check_PROGRAMS = tc-compile tc-cast tc-deque tc-dir tc-format tc-io tc-link \ +check_PROGRAMS = tc-compile tc-cast tc-deque tc-dir tc-format tc-io \ tc-list tc-list2 tc-map tc-memmem tc-misc tc-netio \ tc-option tc-proc tc-rand tc-realpath \ tc-shconfig tc-strchr2 tc-string tc-strquote \ @@ -44,7 +45,6 @@ tc_dir_LDADD = libHX.la tc_format_LDADD = libHX.la tc_io_LDADD = libHX.la -tc_link_LDADD = libHX.la tc_list_LDADD = libHX.la tc_list2_LDADD = libHX.la tc_list2_CFLAGS = ${AM_CFLAGS} -O2 -fstrict-aliasing @@ -71,7 +71,6 @@ tx-strquote tx-time TESTS += tx-strchr2 tx-strquote tx_cast_SOURCES = tx-cast.cpp -tx_cast_CXXFLAGS = ${AM_CXXFLAGS} -std=c++98 tx_cast_LDADD = libHX.la -lm tx_compile_SOURCES = tx-compile.cpp tx_compile_LDADD = libHX.la diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libHX-4.2/src/io.c new/libHX-4.4/src/io.c --- old/libHX-4.2/src/io.c 2021-10-17 15:36:53.000000000 +0200 +++ new/libHX-4.4/src/io.c 2022-03-15 14:09:54.000000000 +0100 @@ -26,12 +26,18 @@ # include <dirent.h> # include <unistd.h> #endif +#if __linux__ +# include <sys/sendfile.h> +#endif #include <libHX/ctype_helper.h> #include <libHX/defs.h> #include <libHX/io.h> #include <libHX/misc.h> #include <libHX/string.h> #include "internal.h" +#ifndef O_CLOEXEC +# define O_CLOEXEC 0 +#endif struct HXdir { #if defined _WIN32 @@ -160,46 +166,72 @@ EXPORT_SYMBOL int HX_copy_file(const char *src, const char *dest, unsigned int opts, ...) { - char buf[MAXLNLEN]; + static const size_t bufsize = 0x10000; + void *buf; unsigned int extra_flags = 0; - int dd, eax = 0, sd, l; + int srcfd, dstfd; - if ((sd = open(src, O_RDONLY | O_BINARY)) < 0) + buf = malloc(bufsize); + if (buf == nullptr) + return -errno; + srcfd = open(src, O_RDONLY | O_BINARY); + if (srcfd < 0) { + free(buf); return -errno; + } if (opts & HXF_KEEP) extra_flags = O_EXCL; - dd = open(dest, O_WRONLY | O_BINARY | O_CREAT | O_TRUNC | - extra_flags, S_IRUGO | S_IWUGO); - if (dd < 0) { - eax = errno; - close(sd); - errno = eax; - if (extra_flags != 0 && eax == EEXIST) - return 1; - return -errno; + dstfd = open(dest, O_WRONLY | O_BINARY | O_CREAT | O_TRUNC | + extra_flags, S_IRUGO | S_IWUGO); + if (dstfd < 0) { + int saved_errno = errno; + free(buf); + close(srcfd); + return -(errno = saved_errno); } - while ((l = read(sd, buf, MAXLNLEN)) > 0 && write(dd, buf, l) > 0) - ; - close(sd); - if (opts & (HXF_UID | HXF_GID)) { struct stat sb; long uid, gid; va_list argp; va_start(argp, opts); - fstat(dd, &sb); + if (fstat(dstfd, &sb) < 0) { + int saved_errno = errno; + unlink(dest); + close(dstfd); + close(srcfd); + return -(errno = saved_errno); + } uid = sb.st_uid; gid = sb.st_gid; if (opts & HXF_UID) uid = va_arg(argp, long); if (opts & HXF_GID) gid = va_arg(argp, long); - if (fchown(dd, uid, gid) < 0) - {}; + if (fchown(dstfd, uid, gid) < 0) { + int saved_errno = errno; + unlink(dest); + close(dstfd); + close(srcfd); + return -(errno = saved_errno); + } va_end(argp); } - close(dd); + + while (true) { + ssize_t rdret = HX_sendfile(dstfd, srcfd, SIZE_MAX); + if (rdret == 0) + break; + if (rdret < 0 && errno != EINTR) { + int saved_errno = errno; + close(srcfd); + close(dstfd); + return -(errno = saved_errno); + } + } + close(srcfd); + close(dstfd); + free(buf); return 1; } @@ -584,6 +616,72 @@ return done; } +#if __linux__ +static ssize_t HX_sendfile_linux(int dst, int src, size_t count) +{ + long pagesize = sysconf(_SC_PAGE_SIZE); + size_t xfersize; + ssize_t ret, xferd = 0; + + if (pagesize < 0) + pagesize = 4096; + xfersize = SSIZE_MAX - pagesize; + if (count > xfersize) + count = xfersize; + while ((ret = sendfile(dst, src, nullptr, count)) > 0) + xferd += ret; + if (xferd > 0) + return xferd; + if (ret < 0) + return -errno; + return 0; +} +#endif + +static ssize_t HX_sendfile_rw(int dst, int src, size_t count) +{ + static const size_t bufsize = 0x10000; + size_t xferd = 0; + ssize_t ret; + void *buf = malloc(bufsize); + if (buf == nullptr) + return -ENOMEM; + if (count > SSIZE_MAX) + count = SSIZE_MAX; + while (count > 0) { + size_t readsize = bufsize; + if (count < readsize) + readsize = count; + ret = HXio_fullread(src, buf, readsize); + if (ret < 0) { + errno = -ret; + break; + } + ret = HXio_fullwrite(dst, buf, ret); + if (ret < 0) { + errno = -ret; + break; + } + xferd += ret; + count -= ret; + } + if (xferd > 0) + return xferd; + if (ret < 0) + return -errno; + return 0; +} + +EXPORT_SYMBOL ssize_t HX_sendfile(int dst, int src, size_t count) +{ +#if __linux__ + ssize_t ret = HX_sendfile_linux(dst, src, count); + if (ret != -ENOSYS) + return ret; +#endif + return HX_sendfile_rw(dst, src, count); +} + EXPORT_SYMBOL char *HX_slurp_fd(int fd, size_t *outsize) { struct stat sb; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libHX-4.2/src/libHX.map new/libHX-4.4/src/libHX.map --- old/libHX-4.2/src/libHX.map 2021-10-17 15:36:53.000000000 +0200 +++ new/libHX-4.4/src/libHX.map 2022-03-15 14:09:54.000000000 +0100 @@ -143,3 +143,10 @@ HX_unit_size; HX_unit_size_cu; } LIBHX_3.27; + +LIBHX_4.3 { +global: + HX_sendfile; + HX_unit_seconds; + HX_strtoull_sec; +} LIBHX_4.2; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libHX-4.2/src/opt.c new/libHX-4.4/src/opt.c --- old/libHX-4.2/src/opt.c 2021-10-17 15:36:53.000000000 +0200 +++ new/libHX-4.4/src/opt.c 2022-03-15 14:09:54.000000000 +0100 @@ -777,6 +777,9 @@ *argv = nvec; if (argc != NULL) *argc = argk; + /* pointers are owned by nvec/argv now */ + HXdeque_free(ps.remaining); + ps.remaining = nullptr; } } else if (ret < 0) { if (!(ps.flags & HXOPT_QUIET)) @@ -788,8 +791,8 @@ else if (ps.flags & HXOPT_USAGEONERR) HX_getopt_usage(&ps.cbi, stderr); } - - HXdeque_free(ps.remaining); + if (ps.remaining != nullptr) + HXdeque_genocide2(ps.remaining, free); return ret; out_errno: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libHX-4.2/src/proc.c new/libHX-4.4/src/proc.c --- old/libHX-4.2/src/proc.c 2021-10-17 15:36:53.000000000 +0200 +++ new/libHX-4.4/src/proc.c 2022-03-15 14:09:54.000000000 +0100 @@ -18,6 +18,9 @@ # include <sys/resource.h> #endif #include <libHX/proc.h> +#ifdef _WIN32 +# include <winsock2.h> +#endif #if defined(HAVE_INITGROUPS) && defined(HAVE_SETGID) #include <grp.h> @@ -188,27 +191,24 @@ HXproc_run_async(const char *const *argv, struct HXproc *proc) { int pipes[3][2], nullfd = -1, ret, saved_errno; - unsigned int t; if (argv == NULL || *argv == NULL) return -EFAULT; - - proc->p_stdin = proc->p_stdout = proc->p_stderr = -1; - - t = (proc->p_flags & (HXPROC_STDIN | HXPROC_NULL_STDIN)) == - (HXPROC_STDIN | HXPROC_NULL_STDIN); - t |= (proc->p_flags & (HXPROC_STDOUT | HXPROC_NULL_STDOUT)) == - (HXPROC_STDOUT | HXPROC_NULL_STDOUT); - t |= (proc->p_flags & (HXPROC_STDERR | HXPROC_NULL_STDERR)) == - (HXPROC_STDERR | HXPROC_NULL_STDERR); - if (t > 0) + if ((proc->p_flags & (HXPROC_STDIN | HXPROC_NULL_STDIN)) == + (HXPROC_STDIN | HXPROC_NULL_STDIN)) + return -EINVAL; + if ((proc->p_flags & (HXPROC_STDOUT | HXPROC_NULL_STDOUT)) == + (HXPROC_STDOUT | HXPROC_NULL_STDOUT)) + return -EINVAL; + if ((proc->p_flags & (HXPROC_STDERR | HXPROC_NULL_STDERR)) == + (HXPROC_STDERR | HXPROC_NULL_STDERR)) return -EINVAL; - if (proc->p_flags & (HXPROC_NULL_STDIN | HXPROC_NULL_STDOUT | HXPROC_NULL_STDERR)) { if ((nullfd = open(NULL_DEVICE, O_RDWR)) < 0) return -errno; } + proc->p_stdin = proc->p_stdout = proc->p_stderr = -1; if ((ret = HXproc_build_pipes(proc, pipes)) <= 0) { saved_errno = errno; HXproc_close_pipes(pipes); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libHX-4.2/src/socket.c new/libHX-4.4/src/socket.c --- old/libHX-4.2/src/socket.c 2021-10-17 15:36:53.000000000 +0200 +++ new/libHX-4.4/src/socket.c 2022-03-15 14:09:54.000000000 +0100 @@ -22,14 +22,31 @@ #include <libHX/proc.h> #include <libHX/socket.h> #include "internal.h" +#ifdef _WIN32 +# define STUPIDWIN(x) reinterpret_cast(char *, (x)) +#else +# define STUPIDWIN(x) (x) +#endif +#if defined(__sunos__) && !defined(SO_PROTOCOL) +# define SO_PROTOCOL SO_PROTOTYPE +#endif static int try_sk_from_env(int fd, const struct addrinfo *ai, const char *intf) { int value = 0; socklen_t optlen = sizeof(value); - int ret = getsockopt(fd, SOL_SOCKET, SO_ACCEPTCONN, &value, &optlen); + int ret = getsockopt(fd, SOL_SOCKET, SO_ACCEPTCONN, STUPIDWIN(&value), &optlen); if (ret < 0 || value == 0) return -1; +#ifdef _WIN32 + WSAPROTOCOL_INFO protinfo; + optlen = sizeof(protinfo); + ret = getsockopt(fd, SOL_SOCKET, SO_PROTOCOL_INFO, STUPIDWIN(&protinfo), &optlen); + if (ret < 0 || protinfo.iAddressFamily != ai->ai_family || + protinfo.iSocketType != ai->ai_socktype || + protinfo.iProtocol != ai->ai_protocol) + return -1; +#else optlen = sizeof(value); ret = getsockopt(fd, SOL_SOCKET, SO_DOMAIN, &value, &optlen); if (ret < 0 || value != ai->ai_family) @@ -42,6 +59,7 @@ ret = getsockopt(fd, SOL_SOCKET, SO_PROTOCOL, &value, &optlen); if (ret < 0 || value != ai->ai_protocol) return -1; +#endif struct sockaddr_storage addr; memset(&addr, 0, sizeof(addr)); optlen = sizeof(addr); @@ -54,6 +72,7 @@ return -1; if (intf == nullptr) return fd; +#ifdef SO_BINDTODEVICE char ifname[32]; optlen = sizeof(ifname); ret = getsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, ifname, &optlen); @@ -65,6 +84,7 @@ ifname[sizeof(ifname)-1] = '\0'; if (strcmp(intf, ifname) != 0) return -1; +#endif return fd; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libHX-4.2/src/string.c new/libHX-4.4/src/string.c --- old/libHX-4.2/src/string.c 2021-10-17 15:36:53.000000000 +0200 +++ new/libHX-4.4/src/string.c 2022-03-15 14:09:54.000000000 +0100 @@ -1004,3 +1004,131 @@ } return ipart; } + +#define SECONDS_PER_YEAR 31557600 +#define SECONDS_PER_MONTH 2629800 + +static const struct { + const char name[8]; + unsigned int len; + uint32_t mult; +} time_multiplier[] = { + {"seconds", 7, 1}, + {"second", 6, 1}, + {"sec", 3, 1}, + {"s", 1, 1}, + {"minutes", 7, 60}, + {"minute", 6, 60}, + {"min", 3, 60}, + {"hours", 5, 3600}, + {"hour", 4, 3600}, + {"h", 1, 3600}, + {"days", 4, 86400}, + {"day", 3, 86400}, + {"d", 1, 86400}, + {"weeks", 5, 604800}, + {"week", 4, 604800}, + {"months", 6, SECONDS_PER_MONTH}, + {"month", 5, SECONDS_PER_MONTH}, + {"years", 5, SECONDS_PER_YEAR}, + {"year", 4, SECONDS_PER_YEAR}, + {"y", 1, SECONDS_PER_YEAR}, +}; + +EXPORT_SYMBOL unsigned long long HX_strtoull_sec(const char *s, char **out_end) +{ + unsigned long long seconds = 0; + + while (*s != '\0') { + while (HX_isspace(*s)) + ++s; + if (*s == '-') { + break; + } + char *end = nullptr; + unsigned long long num = strtoull(s, &end, 10); + if (end == s) + break; + s = end; + while (HX_isspace(*s)) + ++s; + if (!HX_isalpha(*s)) { + seconds += num; + continue; + } + unsigned int i; + for (i = 0; i < ARRAY_SIZE(time_multiplier); ++i) + if (strncmp(s, time_multiplier[i].name, + time_multiplier[i].len) == 0 && + !HX_isalpha(s[time_multiplier[i].len])) + break; + if (i == ARRAY_SIZE(time_multiplier)) + break; + seconds += num * time_multiplier[i].mult; + s += time_multiplier[i].len; + } + if (out_end != nullptr) + *out_end = const_cast(char *, s); + return seconds; +} + +EXPORT_SYMBOL char *HX_unit_seconds(char *out, size_t outsize, + unsigned long long secs, unsigned int flags) +{ + unsigned long years = 0, months = 0, weeks = 0, days, hours, mins; + char buf[HXSIZEOF_Z64+4]; + if (flags & HXUNIT_YEARS) { + years = secs / SECONDS_PER_YEAR; + secs %= SECONDS_PER_YEAR; + } + if (flags & HXUNIT_MONTHS) { + months = secs / SECONDS_PER_MONTH; + secs %= SECONDS_PER_MONTH; + } + if (flags & HXUNIT_WEEKS) { + weeks = secs / 604800; + secs %= 604800; + } + days = secs / 86400; + secs %= 86400; + hours = secs / 3600; + secs %= 3600; + mins = secs / 60; + secs %= 60; + *out = '\0'; + if (years > 0) { + snprintf(buf, ARRAY_SIZE(buf), "%luy", years); + HX_strlcat(out, buf, outsize); + } + if (months == 1) { + HX_strlcat(out, "1month", outsize); + } else if (months > 0) { + snprintf(buf, ARRAY_SIZE(buf), "%lumonths", months); + HX_strlcat(out, buf, outsize); + } + if (weeks == 1) { + HX_strlcat(out, "1week", outsize); + } else if (weeks > 0) { + snprintf(buf, ARRAY_SIZE(buf), "%luweeks", weeks); + HX_strlcat(out, buf, outsize); + } + if (days > 0) { + snprintf(buf, ARRAY_SIZE(buf), "%lud", days); + HX_strlcat(out, buf, outsize); + } + if (hours > 0) { + snprintf(buf, ARRAY_SIZE(buf), "%luh", hours); + HX_strlcat(out, buf, outsize); + } + if (mins > 0) { + snprintf(buf, ARRAY_SIZE(buf), "%lumin", mins); + HX_strlcat(out, buf, outsize); + } + if (secs > 0 || + (years == 0 && months == 0 && weeks == 0 && + days == 0 && hours == 0 && mins == 0)) { + snprintf(buf, ARRAY_SIZE(buf), "%llus", secs); + HX_strlcat(out, buf, outsize); + } + return out; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libHX-4.2/src/tc-io.c new/libHX-4.4/src/tc-io.c --- old/libHX-4.2/src/tc-io.c 2021-10-17 15:36:53.000000000 +0200 +++ new/libHX-4.4/src/tc-io.c 2022-03-15 14:09:54.000000000 +0100 @@ -1,11 +1,39 @@ +#include <errno.h> +#include <fcntl.h> +#include <stdint.h> #include <stdio.h> +#include <string.h> +#include <unistd.h> #include <libHX/io.h> +static void sf(void) +{ + int src = open("tc-io.c", O_RDONLY); + if (src < 0) + return; + int dst = open("/dev/null", O_WRONLY); + if (dst < 0) { + close(src); + return; + } + ssize_t ret = HX_sendfile(dst, src, SIZE_MAX); + printf("sendfile transferred %zd bytes\n", ret); + close(dst); + close(src); +} + int main(void) { size_t z; char *s = HX_slurp_file("tc-io.c", &z); printf("%s\n", s); printf("Dumped %zu bytes\n", z); + + sf(); + int ret = HX_copy_file("tc-io.c", "tciocopy.txt", 0); + if (ret <= 0) + fprintf(stderr, "HX_copy_file: %s\n", strerror(errno)); + else + fprintf(stderr, "copy_file ok\n"); return 0; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libHX-4.2/src/tc-link.c new/libHX-4.4/src/tc-link.c --- old/libHX-4.2/src/tc-link.c 2021-10-17 15:36:53.000000000 +0200 +++ new/libHX-4.4/src/tc-link.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,156 +0,0 @@ -#include <stdlib.h> -#include <libHX.h> -#include "internal.h" - -static void *funcs[] = { - HXdeque_init, - HXdeque_push, - HXdeque_pop, - HXdeque_unshift, - HXdeque_shift, - HXdeque_move, - HXdeque_del, - HXdeque_free, - HXdeque_find, - HXdeque_get, - HXdeque_genocide2, - HXdeque_to_vec, - HX_dlopen, - HX_dlsym, - HX_dlclose, - HX_dlerror, - HXformat_init, - HXformat_free, - HXformat_add, - HXformat_aprintf, - HXformat_fprintf, - HXformat_sprintf, - HXdir_open, - HXdir_read, - HXdir_close, - HX_copy_file, - HX_copy_dir, - HX_mkdir, - HX_readlink, - HX_realpath, - HX_rrmdir, - HXio_fullread, - HXio_fullwrite, - HXmap_free, - HXhash_jlookup3, - HXhash_jlookup3s, - HXhash_djb2, - HXmap_init5, - HXmap_init, - HXmap_find, - HXmap_get, - HXmap_add, - HXmap_del, - HXmap_keysvalues, - HXmap_travinit, - HXmap_traverse, - HXmap_travfree, - HXmap_qfe, - HXmc_strinit, - HXmc_meminit, - HXmc_strcpy, - HXmc_memcpy, - HXmc_length, - HXmc_setlen, - HXmc_trunc, - HXmc_strcat, - HXmc_memcat, - HXmc_strpcat, - HXmc_mempcat, - HXmc_strins, - HXmc_memins, - HXmc_memdel, - HXmc_free, - HXmc_zvecfree, - HX_ffs, - HX_fls, - HX_hexdump, - HX_zvecfree, - HX_getopt, - HX_getopt_help, - HX_getopt_help_cb, - HX_getopt_usage, - HX_getopt_usage_cb, - HX_shconfig, - HX_shconfig_map, - HX_shconfig_pv, - HX_shconfig_free, - HXproc_run_async, - HXproc_run_sync, - HXproc_wait, - HX_init, - HX_exit, - HX_rand, - HX_drand, - HX_irand, - HX_basename, - HX_basename_exact, - HX_chomp, - HX_dirname, - HX_getl, - HX_memmem, - HX_split, - HX_split_fixed, - HX_split_inplace, - HX_stpltrim, - HX_strbchr, - HX_strchr2, - HX_strclone, - HX_strdup, - HX_strlcat, - HX_strlcpy, - HX_strlncat, - HX_strlower, - HX_strltrim, - HX_strmid, - HX_strndup, - HX_strnlen, - HX_strrcspn, - HX_strrev, - HX_strrtrim, - HX_strsep, - HX_strsep2, - HX_strquote, - HX_strupper, - HX_time_compare, -#ifdef HAVE_STRUCT_TIMESPEC_TV_NSEC - HX_timespec_add, - HX_timespec_isneg, - HX_timespec_mul, - HX_timespec_mulf, - HX_timespec_neg, - HX_timespec_sub, -#endif -#ifdef HAVE_STRUCT_TIMEVAL_TV_USEC - HX_timeval_sub, -#endif -#ifdef _WIN32 - chown, - fchmod, - fchown, - lchown, - lstat, - mkfifo, - mknod, - readlink, - symlink, - mmap, - munmap, -#endif -}; - -int main(void) -{ - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(funcs); ++i) - printf("%p ", funcs[i]); - printf("\n"); - printf("There are %" HX_SIZET_FMT "u exported functions\n", ARRAY_SIZE(funcs)); - return EXIT_SUCCESS; -} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libHX-4.2/src/tc-list.c new/libHX-4.4/src/tc-list.c --- old/libHX-4.2/src/tc-list.c 2021-10-17 15:36:53.000000000 +0200 +++ new/libHX-4.4/src/tc-list.c 2022-03-15 14:09:54.000000000 +0100 @@ -111,6 +111,8 @@ static void l_shift(void) { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-but-set-variable" /* Check for -Wshadow warnings */ struct object { int value; @@ -130,6 +132,7 @@ HXclist_push(&clh, &q.anchor); x = p = HXclist_pop(&clh, struct object, anchor); printf("%d\n", p->value); +#pragma GCC diagnostic pop } int main(int argc, const char **argv) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libHX-4.2/src/tc-map.c new/libHX-4.4/src/tc-map.c --- old/libHX-4.2/src/tc-map.c 2021-10-17 15:36:53.000000000 +0200 +++ new/libHX-4.4/src/tc-map.c 2022-03-15 14:09:54.000000000 +0100 @@ -25,6 +25,7 @@ #include <sys/time.h> #include "internal.h" #include "map_int.h" +#pragma GCC diagnostic ignored "-Wunused-const-variable" union HXpoly { struct HXmap *map; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libHX-4.2/src/tc-string.c new/libHX-4.4/src/tc-string.c --- old/libHX-4.2/src/tc-string.c 2021-10-17 15:36:53.000000000 +0200 +++ new/libHX-4.4/src/tc-string.c 2022-03-15 14:09:54.000000000 +0100 @@ -90,9 +90,12 @@ { char data[5] = "DATA"; +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat-truncation" if (snprintf(data, sizeof(data), "12345678") >= static_cast(ssize_t, sizeof(data))) printf("Not enough space\n"); +#pragma GCC diagnostic pop printf("String: >%s<\n", data); HX_strlcat(data, "pqrstuv__", 2); @@ -271,11 +274,13 @@ HX_timespec_sub(&d2, &stop, &start); HX_timespec_sub(&d3, &d1, &d2); - printf("%4zu->%4zu: %1ld.%09ld (str=%ld.%09ld mem=%ld.%09ld)\n", + printf("%4zu->%4zu: " HX_TIMESPEC_FMT + " (str=" HX_TIMESPEC_FMT + " mem=" HX_TIMESPEC_FMT ")\n", strlen(ibuf), picksizes[opick], - static_cast(long, d3.tv_sec), d3.tv_nsec, - static_cast(long, d1.tv_sec), d1.tv_nsec, - static_cast(long, d2.tv_sec), d2.tv_nsec + HX_TIMESPEC_EXP(&d3), + HX_TIMESPEC_EXP(&d1), + HX_TIMESPEC_EXP(&d2) ); } } @@ -417,6 +422,64 @@ } } +static void t_time_units(void) +{ + static const struct { + unsigned long long input; + unsigned int flags; + const char expect_out[24]; + } vt[] = { + {31536000, 0, "365d"}, + {31622400, 0, "366d"}, + {31622400, HXUNIT_YEARS, "1y18h"}, + {31622400, HXUNIT_MONTHS, "1y"}, + {31622400, HXUNIT_WEEKS, "1y"}, + {31622400, HXUNIT_MONTHS | HXUNIT_WEEKS, "1y"}, + {2678400, HXUNIT_MONTHS, "1month13h30min"}, + {2592000, HXUNIT_MONTHS, "30d"}, + {608400, HXUNIT_WEEKS, "1week1h"}, + {90061, 0, "1d1h1min1s"}, + {3692, 0, "1h1min32s"}, + {67, 0, "1min7s"}, + {1, 0, "1s"}, + {0, 0, "0s"}, + }; + printf("===== HX_unit_seconds\n"); + for (size_t i = 0; i < ARRAY_SIZE(vt); ++i) { + char out[60]; + char *ret = HX_unit_seconds(out, ARRAY_SIZE(out), vt[i].input, vt[i].flags); + printf("%llus => \"%s\"\n", vt[i].input, ret); + if (strcmp(ret, vt[i].expect_out) != 0) + printf("\tBUG, expected \"%s\"\n", vt[i].expect_out); + } +} + +static void t_time_strto(void) +{ + static const struct { + const char *input; + unsigned long long expect_out; + const char expect_rem[4]; + } vt[] = { + {"1y1month1week1d1h1min1s ", 31557600+2629800+86400*8+3600+60+1, ""}, + {" -1d", 0, "-1d"}, + {"1 -", 1, "-"}, + {"1s", 1, ""}, + {"1min", 60, ""}, + {"0", 0, ""}, + }; + char *end; + printf("===== t_time_strto\n"); + for (size_t i = 0; i < ARRAY_SIZE(vt); ++i) { + unsigned long long q = HX_strtoull_sec(vt[i].input, &end); + printf("\"%s\" => %llus + \"%s\"\n", vt[i].input, q, end); + if (q != vt[i].expect_out) + printf("\tBUG: expected %llus\n", vt[i].expect_out); + if (strcmp(end, vt[i].expect_rem) != 0) + printf("\tBUG: expected remainder \"%s\"\n", vt[i].expect_rem); + } +} + int main(int argc, const char **argv) { hxmc_t *tx = NULL; @@ -448,6 +511,8 @@ t_units(); t_units_cu(); t_units_strto(); + t_time_units(); + t_time_strto(); t_strlcpy(); t_strlcpy2(); HXmc_free(tx); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libHX-4.2/src/time.c new/libHX-4.4/src/time.c --- old/libHX-4.2/src/time.c 2021-10-17 15:36:53.000000000 +0200 +++ new/libHX-4.4/src/time.c 2022-03-15 14:09:54.000000000 +0100 @@ -6,6 +6,7 @@ * General Public License as published by the Free Software Foundation; * either version 2.1 or (at your option) any later version. */ +#include <stdint.h> #include <sys/stat.h> #include <sys/time.h> #include <stdbool.h> @@ -39,38 +40,13 @@ EXPORT_SYMBOL struct timespec *HX_timespec_add(struct timespec *r, const struct timespec *a, const struct timespec *b) { - /* - * Split the value represented by the struct into two - * independent values that can be added individually. - */ - long nsec[2]; - nsec[0] = (a->tv_sec < 0) ? -a->tv_nsec : a->tv_nsec; - nsec[1] = (b->tv_sec < 0) ? -b->tv_nsec : b->tv_nsec; - - r->tv_sec = a->tv_sec + b->tv_sec; - r->tv_nsec = nsec[0] + nsec[1]; - if (r->tv_nsec >= NANOSECOND) { - ++r->tv_sec; - r->tv_nsec -= NANOSECOND; - } else if (r->tv_nsec <= -NANOSECOND) { - --r->tv_sec; - r->tv_nsec += NANOSECOND; - } - - /* Combine again */ - if (r->tv_sec < 0) { - if (r->tv_nsec < 0) { - r->tv_nsec = -r->tv_nsec; - } else if (r->tv_nsec > 0) { - if (++r->tv_sec == 0) - r->tv_nsec = -NANOSECOND + r->tv_nsec; - else - r->tv_nsec = NANOSECOND - r->tv_nsec; - } - } else if (r->tv_sec > 0 && r->tv_nsec < 0) { - --r->tv_sec; - r->tv_nsec = NANOSECOND + r->tv_nsec; - } + long aa = a->tv_sec * NANOSECOND_LL + + ((a->tv_sec >= 0) ? a->tv_nsec : -a->tv_nsec); + long bb = b->tv_sec * NANOSECOND_LL + + ((b->tv_sec >= 0) ? b->tv_nsec : -b->tv_nsec); + long rr = aa + bb; + r->tv_sec = rr / NANOSECOND; + r->tv_nsec = ((r->tv_sec < 0) ? -rr : rr) % NANOSECOND; return r; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libHX-4.2/src/tx-option.cpp new/libHX-4.4/src/tx-option.cpp --- old/libHX-4.2/src/tx-option.cpp 2021-10-17 15:36:53.000000000 +0200 +++ new/libHX-4.4/src/tx-option.cpp 2022-03-15 14:09:54.000000000 +0100 @@ -5,7 +5,9 @@ #endif #include <libHX/option.h> +static unsigned int g_verbose; static const struct HXoption t[] = { + {nullptr, 'v', HXTYPE_NONE | HXOPT_INC, &g_verbose}, HXOPT_AUTOHELP, HXOPT_TABLEEND, }; ++++++ libHX.keyring ++++++ --- /var/tmp/diff_new_pack.j21peP/_old 2022-03-16 21:30:45.459411422 +0100 +++ /var/tmp/diff_new_pack.j21peP/_new 2022-03-16 21:30:45.463411425 +0100 @@ -1,53 +1,26 @@ -----BEGIN PGP PUBLIC KEY BLOCK----- -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 -NGTT6x12 -=QLsa +mDMEYdM5whYJKwYBBAHaRw8BAQdADytr1kM/qc54vO40yIHht0XeDD7sMe1rw8Xo +Nq/LtMO0IEphbiBFbmdlbGhhcmR0IDxqZW5nZWxoQGluYWkuZGU+iJUEExYKAD0W +IQS8oMXDCcrFaedKkhz3bv5dDCI6jwUCYdM5wgIbAwUJCWYBgAQLCQgHBRUKCQgL +BRYCAwEAAh4FAheAAAoJEPdu/l0MIjqPriUBAPLcct0ekiHZHS/mPDaS0I0mh5zy +zaZFuB5FaMpQQgQ5AP45H+SqGxP7BRlsEDajDmcEyM+IPvn22lOGKyR5OKQxDokC +MwQQAQoAHRYhBCNobBCkVpG+ekJRCdY4gYHzWgk4BQJh0zqPAAoJENY4gYHzWgk4 +F7EP/3ZG6rs4l24k/GOvO1CNPM0rHaOccbB3E8BXzTJ6BsKIG1T3X4cokLHAkhmO +8ffw9NYV/HJ1AJyirvHfYFd6nn55aMakbyjo7RmDpmMmpJH5UpbhtqlJkeRQdMni +3bx+9i9E8QFJG6eFaGz8UhCCyzQvuLhawNcA6mPDumQkIri73NnA9vegw8yyDqpr +14fm4Eh+uERzXQ6JkNTqaZuKfyryb4MSluJ6LEUqNv1vqJeCHoE5iQc0WaDPamiP +Dnd3G/k2KHIFTlYdFVKnow0MYo+kyRKxUUL38x/tZ/WEhSv9oiNUOqTZJhkPOHOv +VaHfRdxOGV3845bWngegkXD6KGQvWT1vlfGa9XbNqxWQFqi59malm/jShnd8XJAK +gZuU9pB70lFwCglc+NQLPPrY16cYwFv1L2xU3owhtdiMydTI38Cw7hPteYPkASpa +/1EHf0pPxRhv01RtrPEsGhroXennooFTHe6U0Ay3Z0yBZbRJhoDv8PvBZ4RatdNR +p05qu2SBUWC+neecIHvbguI9x5G8egJ8WsGgDAuMcvWsW95H9oj/aONAgtL6LcsT +KHaPI9senfBTYI+ak+E9sHi/kaQIl5umvf8+B2CAh4QPhmkYvGtINH+HCZI6WdyE +tIsg+JklBgFwSBus9zHHUwwBfio2PgIlocRL6SL5Q2amcALPuDgEYdM5whIKKwYB +BAGXVQEFAQEHQKpjexO72fM4FUcrTh2r6MCyxmAF0CBUpnTQeIk5nVZ2AwEIB4h+ +BBgWCgAmFiEEvKDFwwnKxWnnSpIc927+XQwiOo8FAmHTOcICGwwFCQlmAYAACgkQ +927+XQwiOo/sOgD9GOjmj2blZGtR5attfY46/9B9bBkb8kDW7LACK007YZUBAJr8 +JCfIUFBfm5b/ev80rscAUSp4uTn4Z/W6ywR5STIH +=NTtt -----END PGP PUBLIC KEY BLOCK-----