diff -Nru snapdev-1.1.38.0~lunar/debian/changelog snapdev-1.1.39.0~lunar/debian/changelog --- snapdev-1.1.38.0~lunar/debian/changelog 2023-11-10 21:32:29.000000000 +0000 +++ snapdev-1.1.39.0~lunar/debian/changelog 2023-12-10 23:11:37.000000000 +0000 @@ -1,4 +1,12 @@ -snapdev (1.1.38.0~lunar) lunar; urgency=high +snapdev (1.1.39.0~lunar) lunar; urgency=high + + * Added min()/max() for timespec_ex. + * Extracted stream_fd.h from isatty.h. + * Added a function to detect whether a timestamp is in the future or not. + + -- Alexis Wilke Sun, 10 Dec 2023 15:11:37 -0800 + +snapdev (1.1.38.0~jammy) jammy; urgency=high * Added another #include . diff -Nru snapdev-1.1.38.0~lunar/snapdev/CMakeLists.txt snapdev-1.1.39.0~lunar/snapdev/CMakeLists.txt --- snapdev-1.1.38.0~lunar/snapdev/CMakeLists.txt 2023-09-01 02:22:42.000000000 +0000 +++ snapdev-1.1.39.0~lunar/snapdev/CMakeLists.txt 2023-11-26 04:38:56.000000000 +0000 @@ -80,6 +80,7 @@ safe_variable.h sizeof_bitfield.h static_to_dynamic_buffer.h + stream_fd.h stringize.h string_replace_many.h timespec_ex.h diff -Nru snapdev-1.1.38.0~lunar/snapdev/isatty.h snapdev-1.1.39.0~lunar/snapdev/isatty.h --- snapdev-1.1.38.0~lunar/snapdev/isatty.h 2023-02-25 21:33:35.000000000 +0000 +++ snapdev-1.1.39.0~lunar/snapdev/isatty.h 2023-11-26 04:36:12.000000000 +0000 @@ -17,12 +17,11 @@ // along with this program. If not, see . #pragma once -// C++ +// self // -#include -#include -#include -#include +#include + + // C // @@ -35,26 +34,6 @@ -namespace detail -{ - -template> -class our_basic_filebuf - : public std::basic_filebuf<_CharT, _Traits> -{ -public: - std::__c_file * file() throw() - { - //return std::basic_filebuf<_CharT, _Traits>::_M_file.file(); - return this->_M_file.file(); - } -}; - -} // namespace detail - - - /** \brief Check whether a C++ iostream is a TTY. * * This function checks the specified stream and if it represents a TTY @@ -77,50 +56,15 @@ */ template> -bool isatty(std::basic_ios<_CharT, _Traits> const & s) +bool isatty(std::basic_ios<_CharT, _Traits> const & stream) { - // in most cases, we use cin, cout, cerr, or clog which are all - // stdio_sync_filebuf<> objects - { - typedef __gnu_cxx::stdio_sync_filebuf<_CharT, _Traits> io_sync_buffer_t; - io_sync_buffer_t * buffer(dynamic_cast(s.rdbuf())); - if(buffer != nullptr) - { - return ::isatty(fileno(buffer->file())); - } - } - - // in this case, we first do a dynamic_cast<>() to make sure we find the - // correct buffer; if present we can do a static_cast<>() to gain access - // to the _M_file field and thus the file() function (there is also an - // fd() function, but to be consistent with the other cases, I used a - // file() like function only) - { - typedef std::basic_filebuf<_CharT, _Traits> file_buffer_t; - file_buffer_t * file_buffer(dynamic_cast(s.rdbuf())); - if(file_buffer != nullptr) - { - typedef detail::our_basic_filebuf<_CharT, _Traits> hack_buffer_t; - hack_buffer_t * buffer(static_cast(file_buffer)); - if(buffer != nullptr) - { - return ::isatty(fileno(buffer->file())); - } - } - } - - // older versions (C++98) used this class -- it is probably never - // going to be true so I put it last + int const r(stream_fd(stream)); + if(r < 0) { - typedef __gnu_cxx::stdio_filebuf<_CharT, _Traits> io_buffer_t; - io_buffer_t * buffer(dynamic_cast(s.rdbuf())); - if(buffer != nullptr) - { - return ::isatty(fileno(buffer->file())); - } + return false; } - return false; + return ::isatty(r); } diff -Nru snapdev-1.1.38.0~lunar/snapdev/stream_fd.h snapdev-1.1.39.0~lunar/snapdev/stream_fd.h --- snapdev-1.1.38.0~lunar/snapdev/stream_fd.h 1970-01-01 00:00:00.000000000 +0000 +++ snapdev-1.1.39.0~lunar/snapdev/stream_fd.h 2023-11-26 04:35:37.000000000 +0000 @@ -0,0 +1,144 @@ +// Copyright (c) 2011-2023 Made to Order Software Corp. All Rights Reserved +// +// https://snapwebsites.org/project/snapdev +// contact@m2osw.com +// +// 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 +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +#pragma once + +// C++ +// +//#include +#include +#include +#include + +// C +// +//#include + + + +namespace snapdev +{ + + + +namespace detail +{ + +template> +class our_basic_filebuf + : public std::basic_filebuf<_CharT, _Traits> +{ +public: + std::__c_file * file() throw() + { + //return std::basic_filebuf<_CharT, _Traits>::_M_file.file(); + return this->_M_file.file(); + } +}; + +} // namespace detail + + + +/** \brief Retrieve the FILE object of a C++ stream. + * + * This function attempts to retrieve a FILE object from a C++ stream. + * This assumes the stream is an fstream of some sort. + * + * \tparam _CharT type of character this stream handles. + * \tparam _Traits traits of the characters based on CharT by default. + * \param[in] stream The stream to check. + * + * \return the stream file object or nullptr on failure. + */ +template> +FILE * stream_file(std::basic_ios<_CharT, _Traits> const & stream) +{ + // in most cases, we use cin, cout, cerr, or clog which are all + // stdio_sync_filebuf<> objects + { + typedef __gnu_cxx::stdio_sync_filebuf<_CharT, _Traits> io_sync_buffer_t; + io_sync_buffer_t * buffer(dynamic_cast(stream.rdbuf())); + if(buffer != nullptr) + { + return buffer->file(); + } + } + + // in this case, we first do a dynamic_cast<>() to make sure we find the + // correct buffer; if present we can do a static_cast<>() to gain access + // to the _M_file field and thus the file() function (there is also an + // fd() function, but to be consistent with the other cases, I used a + // file() like function only) + { + typedef std::basic_filebuf<_CharT, _Traits> file_buffer_t; + file_buffer_t * file_buffer(dynamic_cast(stream.rdbuf())); + if(file_buffer != nullptr) + { + typedef detail::our_basic_filebuf<_CharT, _Traits> hack_buffer_t; + hack_buffer_t * buffer(static_cast(file_buffer)); + if(buffer != nullptr) + { + return buffer->file(); + } + } + } + + // older versions (C++98) used this class -- it is probably never + // going to be true so I put it last + { + typedef __gnu_cxx::stdio_filebuf<_CharT, _Traits> io_buffer_t; + io_buffer_t * buffer(dynamic_cast(stream.rdbuf())); + if(buffer != nullptr) + { + return buffer->file(); + } + } + + return nullptr; +} + + +/** \brief Retrieve the file descriptor of a C++ stream. + * + * This function attempts to retrieve a file descriptor from a C++ stream. + * This assumes the stream is an fstream of some sort. + * + * \tparam _CharT type of character this stream handles. + * \tparam _Traits traits of the characters based on CharT by default. + * \param[in] stream The stream to check. + * + * \return the stream file descriptor or -1 on failure. + */ +template> +int stream_fd(std::basic_ios<_CharT, _Traits> const & stream) +{ + FILE * f(stream_file<_CharT, _Traits>(stream)); + if(f == nullptr) + { + return -1; + } + return fileno(f); +} + + + +} // namespace snapdev +// vim: ts=4 sw=4 et diff -Nru snapdev-1.1.38.0~lunar/snapdev/timespec_ex.h snapdev-1.1.39.0~lunar/snapdev/timespec_ex.h --- snapdev-1.1.38.0~lunar/snapdev/timespec_ex.h 2023-11-06 04:48:03.000000000 +0000 +++ snapdev-1.1.39.0~lunar/snapdev/timespec_ex.h 2023-11-26 05:03:54.000000000 +0000 @@ -82,6 +82,10 @@ DECLARE_EXCEPTION(timespec_ex_exception, overflow); +class timespec_ex; +inline timespec_ex now(clockid_t clk_id = CLOCK_REALTIME); + + class timespec_ex : public timespec { @@ -1285,6 +1289,56 @@ { return compare(t) >= 0; } + + + /** \brief Return the minimum possible timespec. + * + * This function returns a timespec with the smallest possible time. + * + * \return A timespec_ex with the minimum possible time. + */ + static timespec_ex min() + { + return timespec_ex(std::numeric_limits::min(), 0); + } + + + /** \brief Return the maximum possible timespec. + * + * This function returns a timespec with the smallest possible time. + * + * \return A timespec_ex with the minimum possible time. + */ + static timespec_ex max() + { + return timespec_ex(std::numeric_limits::max(), 999'999'999L); + } + + + /** \brief Check whether time is in the future. + * + * This function checks whether this timespec_ex represents a time in the + * future. + * + * You may pass an \p epsilon parameter to allow a gap between now and + * the time you consider in the future. By default, \p epsilon is set to + * zero. If you may pass a negative time in which case the threshold is + * moved in the past (i.e. a -5 second epsilon means this function returns + * true if "this >= now - 5 second"). + * + * \note + * If this time is exactly equal to now(), then the function returns + * false (assuming an epsilon of 0). + * + * \param[in] epsilon The allowed discrepancy, 0 by default. + * + * \return true if time is in the future. + */ + bool is_in_the_future(snapdev::timespec_ex const & epsilon = { 0, 0 }) const + { + snapdev::timespec_ex const threshold(now() + epsilon); + return *this > threshold; + } }; @@ -1303,7 +1357,7 @@ * * \return A timespec_ex object with "now" as the time. */ -inline timespec_ex now(clockid_t clk_id = CLOCK_REALTIME) +inline timespec_ex now(clockid_t clk_id) { timespec_ex n; int const r(clock_gettime(clk_id, &n));