diff options
-rw-r--r-- | CMakeLists.txt | 7 | ||||
-rw-r--r-- | LICENSE | 2 | ||||
-rw-r--r-- | sdn.cpp | 44 |
3 files changed, 34 insertions, 19 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 175139a..50ebf3b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,13 +7,6 @@ if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wno-misleading-indentation -pedantic") endif () -# Since we use a language with slow compilers, let's at least use a fast linker -execute_process (COMMAND ${CMAKE_CXX_COMPILER} -fuse-ld=gold -Wl,--version - ERROR_QUIET OUTPUT_VARIABLE ld_version) -if ("${ld_version}" MATCHES "GNU gold") - set (CMAKE_EXE_LINKER_FLAGS "-fuse-ld=gold ${CMAKE_EXE_LINKER_FLAGS}") -endif () - find_package (PkgConfig REQUIRED) pkg_check_modules (NCURSESW QUIET ncursesw) @@ -1,4 +1,4 @@ -Copyright (c) 2017 - 2023, Přemysl Eric Janouch <p@janouch.name> +Copyright (c) 2017 - 2024, Přemysl Eric Janouch <p@janouch.name> Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. @@ -1,7 +1,7 @@ // // sdn: simple directory navigator // -// Copyright (c) 2017 - 2023, Přemysl Eric Janouch <p@janouch.name> +// Copyright (c) 2017 - 2024, Přemysl Eric Janouch <p@janouch.name> // // Permission to use, copy, modify, and/or distribute this software for any // purpose with or without fee is hereby granted. @@ -640,6 +640,25 @@ fun ls_format (const entry &e, bool for_target) -> chtype { return format; } +fun suffixize (off_t size, unsigned shift, wchar_t suffix, std::wstring &out) + -> bool { + // Prevent implementation-defined and undefined behaviour + if (size < 0 || shift >= sizeof size * 8) + return false; + + off_t divided = size >> shift; + if (divided >= 10) { + out.assign (std::to_wstring (divided)).append (1, suffix); + return true; + } else if (divided > 0) { + unsigned times_ten = size / double (off_t (1) << shift) * 10.0; + out.assign ({L'0' + wchar_t (times_ten / 10), L'.', + L'0' + wchar_t (times_ten % 10), suffix}); + return true; + } + return false; +} + fun make_entry (const struct dirent *f) -> entry { entry e; e.filename = f->d_name; @@ -690,11 +709,12 @@ fun make_entry (const struct dirent *f) -> entry { ? apply_attrs (grp->second, 0) : apply_attrs (to_wstring (info.st_gid), 0); - auto size = to_wstring (info.st_size); - if (info.st_size >> 40) size = to_wstring (info.st_size >> 40) + L"T"; - else if (info.st_size >> 30) size = to_wstring (info.st_size >> 30) + L"G"; - else if (info.st_size >> 20) size = to_wstring (info.st_size >> 20) + L"M"; - else if (info.st_size >> 10) size = to_wstring (info.st_size >> 10) + L"K"; + std::wstring size; + if (!suffixize (info.st_size, 40, L'T', size) && + !suffixize (info.st_size, 30, L'G', size) && + !suffixize (info.st_size, 20, L'M', size) && + !suffixize (info.st_size, 10, L'K', size)) + size = to_wstring (info.st_size); e.cols[entry::SIZE] = apply_attrs (size, 0); wchar_t buf[32] = L""; @@ -910,14 +930,16 @@ readfail: } fun run_program (initializer_list<const char *> list, const string &filename) { + auto args = (!filename.empty() && filename.front() == '-' ? " -- " : " ") + + shell_escape (filename); if (g.ext_helpers) { - // XXX: this doesn't try them all out, though it shouldn't make any - // noticeable difference + // XXX: this doesn't try them all out, + // though it shouldn't make any noticeable difference const char *found = nullptr; for (auto program : list) if ((found = program)) break; - g.ext_helper = found + (" " + shell_escape (filename)); + g.ext_helper.assign (found).append (args); g.quitting = true; return; } @@ -933,8 +955,8 @@ fun run_program (initializer_list<const char *> list, const string &filename) { tcsetpgrp (STDOUT_FILENO, getpgid (0)); for (auto program : list) - if (program) execl ("/bin/sh", "/bin/sh", "-c", (string (program) - + " " + shell_escape (filename)).c_str (), NULL); + if (program) execl ("/bin/sh", "/bin/sh", "-c", + (program + args).c_str (), NULL); _exit (EXIT_FAILURE); default: // ...and make sure of it in the parent as well |