diff --git a/3rdparty/fs_prettyprint.hpp b/3rdparty/fs_prettyprint.hpp new file mode 100644 index 0000000000000000000000000000000000000000..ac269d79494b467f3097a2c1b59d77d5db17ecd4 --- /dev/null +++ b/3rdparty/fs_prettyprint.hpp @@ -0,0 +1,96 @@ +#ifndef RLIB_FS_STATUS_PRETTYPRINT +#define RLIB_FS_STATUS_PRETTYPRINT + +#include <filesystem> +#include <iomanip> +#include <ostream> +#include <string> + +#include <rlib/require/cxx17> + +namespace rlib::prettyprint { + +namespace impl { +inline std::string ftypeToString(const std::filesystem::file_type &t) { + switch(t) { + case std::filesystem::file_type::regular: return "regular file"; + case std::filesystem::file_type::directory: return "directory"; + case std::filesystem::file_type::symlink: return "symlink"; + case std::filesystem::file_type::block: return "block file"; + case std::filesystem::file_type::character: return "character file"; + case std::filesystem::file_type::fifo: return "fifo"; + case std::filesystem::file_type::socket: return "socket"; + case std::filesystem::file_type::unknown: return "unknown"; + case std::filesystem::file_type::none: return "none"; + case std::filesystem::file_type::not_found: return "not_found"; + } + return ""; +} + +inline std::string fsizeToString(const size_t fsize) { + if(fsize < 1024) + return std::to_string(fsize); + const auto KiB = (double)fsize / 1024.; + if(KiB < 1024) return std::to_string(KiB) + "Ki"; + const auto MiB = KiB / 1024.; + if(MiB < 1024) return std::to_string(MiB) + "Mi"; + const auto GiB = MiB / 1024.; + if(GiB < 1024) return std::to_string(GiB) + "Gi"; + const auto TiB = GiB / 1024.; + if(TiB < 1024) return std::to_string(TiB) + "Ti"; + const auto PiB = TiB / 1024.; + return std::to_string(PiB) + "Pi"; +} + +template <typename T> +std::string try_show_file_size(const T &arg) { + try { + return fsizeToString(std::filesystem::file_size(arg)); + } + catch(...) { + return "-"; + } +} +} + +template<typename CharT, typename Traits> +std::basic_ostream<CharT, Traits>& +operator<< (std::basic_ostream<CharT, Traits> &os, const std::filesystem::perms& p) { + return os + << ((p & std::filesystem::perms::owner_read) != std::filesystem::perms::none ? "r" : "-") + << ((p & std::filesystem::perms::owner_write) != std::filesystem::perms::none ? "w" : "-") + << ((p & std::filesystem::perms::owner_exec) != std::filesystem::perms::none ? "x" : "-") + << ((p & std::filesystem::perms::group_read) != std::filesystem::perms::none ? "r" : "-") + << ((p & std::filesystem::perms::group_write) != std::filesystem::perms::none ? "w" : "-") + << ((p & std::filesystem::perms::group_exec) != std::filesystem::perms::none ? "x" : "-") + << ((p & std::filesystem::perms::others_read) != std::filesystem::perms::none ? "r" : "-") + << ((p & std::filesystem::perms::others_write) != std::filesystem::perms::none ? "w" : "-") + << ((p & std::filesystem::perms::others_exec) != std::filesystem::perms::none ? "x" : "-") + ; +} + +template<typename CharT, typename Traits> +std::basic_ostream<CharT, Traits>& +operator<< (std::basic_ostream<CharT, Traits> &os, const std::filesystem::file_type& t) { + return os << impl::ftypeToString(t); +} + +template<typename CharT, typename Traits> +std::basic_ostream<CharT, Traits>& +operator<< (std::basic_ostream<CharT, Traits> &os, const std::filesystem::directory_entry& entry) { +#if RLIB_CXX_STD >= 2020 + auto lastWriteInSysClock = std::chrono::clock_cast<std::chrono::system_clock>(entry.last_write_time()); +#else +#error A BUG NOT RESOLVED NOW. DO NOT USE THIS LIB. + auto lastWriteInSysClock = entry.last_write_time(); +#endif + auto lastWrite = std::chrono::system_clock::to_time_t(lastWriteInSysClock); + return os << entry.status().permissions() << ' ' << impl::try_show_file_size(entry) << ' ' << std::put_time(std::localtime(&lastWrite), "%F %T") << ' ' << entry.status().type(); +} + + + +} // end namespace rlib::prettyprint + + +#endif diff --git a/3rdparty/prettyprint.hpp b/3rdparty/prettyprint.hpp index ce2226a92b3d753826442b16ee18264e0a755839..69916bf930ef19e92cfc33bdf8df54ad0280c59f 100644 --- a/3rdparty/prettyprint.hpp +++ b/3rdparty/prettyprint.hpp @@ -30,10 +30,9 @@ #include <utility> #include <valarray> -#ifndef RLIB_3RD_ENABLE_PRETTYPRINT namespace rlib { namespace _3rdparty { -#endif +// 3rd party code begin namespace pretty_print { namespace detail @@ -451,11 +450,11 @@ namespace std return stream << pretty_print::print_container_helper<T, TChar, TCharTraits>(container); } } -#ifndef RLIB_3RD_ENABLE_PRETTYPRINT +// 3rd party code end. } } // end namespace rlib::3rdparty -#endif // RLIB_3RD_ENABLE_PRETTYPRINT - - +namespace rlib { + namespace prettyprint = ::rlib::_3rdparty::std; +} #endif // H_PRETTY_PRINT diff --git a/3rdparty/test.cc b/3rdparty/test.cc index 89a3519be69d10ca84d89c5094f3b5008c518c00..95c8ef4c9bdf0ddf71fc547b3fcff69614b65472 100644 --- a/3rdparty/test.cc +++ b/3rdparty/test.cc @@ -1,9 +1,9 @@ #include "prettyprint.hpp" #include <rlib/stdio.hpp> #include <list> -using namespace rlib; +using namespace rlib::prettyprint; int main() { - std::list ls {1,3,2}; - _3rdparty::std::operator<<(std::cout, ls); + std::list<int> ls {1,3,2}; + std::cout << ls; } diff --git a/sys/unix_handy.hpp b/sys/unix_handy.hpp index ffc63bc792447fb7f7140dfc0b315367cf8cae9c..c65110bb6fac2704971822aa26f4fce9ab9737c4 100644 --- a/sys/unix_handy.hpp +++ b/sys/unix_handy.hpp @@ -2,6 +2,7 @@ #define RLIB_UNIX_HANDY_HPP_ #include <unistd.h> + #include <sys/socket.h> #include <sys/types.h> #include <netdb.h> @@ -13,6 +14,22 @@ #error rlib/sys/unix_handy.hpp is not for Windows. #endif +namespace rlib { + // args DOES NOT contain the "$0". + inline void execs(std::string path, std::vector<std::string> args) { + const size_t max_args = 1022; + if(args.size() > max_args) + throw std::out_of_range("too many arguments"); + char* arr[max_args + 2]; + arr[0] = (char *)path.c_str(); + for(auto cter = 0; cter < args.size(); ++cter) + arr[cter+1] = (char *)args[cter].c_str(); + arr[args.size() + 1] = 0; + + ::execv(path.c_str(), arr); + } +} + // Deprecated. Use sys/sio.hpp #if 1+1 == 4 namespace rlib {