From 30334296455fc24f102fb4473c99f66e04d85ebf Mon Sep 17 00:00:00 2001 From: Martin Petricek Date: Sat, 15 Aug 2009 18:03:24 +0000 Subject: [PATCH] Ticket #268 (Allow using SI-based size prefixes) * add: switching between old (default) 1024 based "binary" prefixes and SI (1000 based) size prefixes when displaying file sizes Signed-off-by: Ilia Maslakov Size in SI units: changed option name and description. * Changed option name in 'Configuration options' dialog. * Moved description to proper section in man page. * Added russian translation. Signed-off-by: Andrew Borodin --- doc/man/mc.1.in | 6 ++++++ doc/man/ru/mc.1.in | 7 +++++++ src/dir.c | 7 +++++++ src/dir.h | 1 + src/main.c | 7 +++++++ src/main.h | 1 + src/option.c | 3 ++- src/setup.c | 1 + src/util.c | 38 ++++++++++++++++++++++++++++++-------- 9 files changed, 62 insertions(+), 9 deletions(-) diff --git a/doc/man/mc.1.in b/doc/man/mc.1.in index 22f354e11..3d92a6381 100644 --- a/doc/man/mc.1.in +++ b/doc/man/mc.1.in @@ -1614,6 +1614,12 @@ Panel Options, Pause after run and Other Options. .PP .B Panel Options .PP +.I Use SI size units. +If this option is set, Midnight Commander will use SI units (powers of 1000) +when displaying any byte sizes. The suffixes (k, m ...) are shown in lowercase. +If unset (default), Midnight Commander will use binary units (powers of 1024) +and the suffixes are shown in upper case (K, M ...) +.PP .I Show Backup Files. If enabled, the Midnight Commander will show files ending with a tilde. Otherwise, they won't be shown (like GNU's ls option -B). diff --git a/doc/man/ru/mc.1.in b/doc/man/ru/mc.1.in index 39e9530fb..08f31818a 100644 --- a/doc/man/ru/mc.1.in +++ b/doc/man/ru/mc.1.in @@ -1771,6 +1771,13 @@ mc на экране. .PP .B Настройки панелей (Panel Options) .PP +.I Размеры в единицах СИ. +Если эта опция включена, то Midnight Commander отображает размеры файлов +и каталогов в единицах СИ (по основанию 1000). Суффиксы к, м, и т. д. +отображаются в нижнем регистре. По умолчанию опция выключена. В этом случае +Midnight Commander отображат размеры в двоичных единицах (по снованию +1024), и суффиксы К, М, и т. д. отображаются в верхнем регистре. +.PP .I Показывать резервные (Backup) файлы. По умолчанию программа Midnight Commander не показывает файлы, имена которых заканчиваются на '~' (подобно ключу -B команды ls в GNU). diff --git a/src/dir.c b/src/dir.c index 9bd371f16..181140ca4 100644 --- a/src/dir.c +++ b/src/dir.c @@ -45,6 +45,13 @@ int show_backups = 1; /* If false then directories are shown separately from files */ int mix_all_files = 0; +/* + * If true, SI units (1000 based) will be used for + * larger units (kilobyte, megabyte, ...). + * If false binary units (1024 based) will be used. + */ +int kilobyte_si = 0; + /* Reverse flag */ static int reverse = 1; diff --git a/src/dir.h b/src/dir.h index 2a4d92a14..9ee009642 100644 --- a/src/dir.h +++ b/src/dir.h @@ -83,5 +83,6 @@ int if_link_is_exe (const char *full_name, const file_entry *file); extern int show_backups; extern int show_dot_files; extern int mix_all_files; +extern int kilobyte_si; #endif diff --git a/src/main.c b/src/main.c index 04f8d5a57..7fc028ba5 100644 --- a/src/main.c +++ b/src/main.c @@ -883,6 +883,13 @@ toggle_show_hidden (void) update_panels (UP_RELOAD, UP_KEEPSEL); } +void +toggle_kilobyte_si (void) +{ + kilobyte_si = !kilobyte_si; + update_panels (UP_RELOAD, UP_KEEPSEL); +} + /* * Just a hack for allowing url-like pathnames to be accepted from the * command line. diff --git a/src/main.h b/src/main.h index 6e1fe2ce1..aac3ec051 100644 --- a/src/main.h +++ b/src/main.h @@ -11,6 +11,7 @@ void toggle_fast_reload (void); void toggle_mix_all_files (void); void toggle_show_backup (void); void toggle_show_hidden (void); +void toggle_kilobyte_si (void); extern int quote; extern volatile int quit; diff --git a/src/option.c b/src/option.c index 64aad7bd0..176a2cb07 100644 --- a/src/option.c +++ b/src/option.c @@ -78,12 +78,13 @@ static struct { {N_("ma&Rk moves down"), &mark_moves_down, TOGGLE_VARIABLE, 0 }, {N_("show &Hidden files"), &show_dot_files, toggle_show_hidden, 0 }, {N_("show &Backup files"), &show_backups, toggle_show_backup, 0 }, + {N_("Use SI si&ze units"), &kilobyte_si, toggle_kilobyte_si, 0 }, { 0, 0, 0, 0 } }; /* Make sure this corresponds to the check_options structure */ #define OTHER_OPTIONS 13 -#define PANEL_OPTIONS 6 +#define PANEL_OPTIONS 7 static WRadio *pause_radio; diff --git a/src/setup.c b/src/setup.c index 66b1e23dd..256cca147 100644 --- a/src/setup.c +++ b/src/setup.c @@ -148,6 +148,7 @@ static const struct { int *opt_addr; } int_options [] = { { "show_backups", &show_backups }, + { "kilobyte_si", &kilobyte_si }, { "show_dot_files", &show_dot_files }, { "verbose", &verbose }, { "mark_moves_down", &mark_moves_down }, diff --git a/src/util.c b/src/util.c index 264918258..3d5a5c81b 100644 --- a/src/util.c +++ b/src/util.c @@ -53,6 +53,7 @@ #include "strutil.h" #include "fileopctx.h" #include "file.h" /* copy_file_file() */ +#include "dir.h" #ifdef HAVE_CHARSET #include "charsets.h" @@ -271,11 +272,11 @@ size_trunc (double size) const char *xtra = ""; if (size > 999999999L){ - divisor = 1024; - xtra = "K"; + divisor = kilobyte_si?1000:1024; + xtra = kilobyte_si?"k":"K"; if (size/divisor > 999999999L){ - divisor = 1024*1024; - xtra = "M"; + divisor = kilobyte_si?(1000*1000):(1024*1024); + xtra = kilobyte_si?"m":"M"; } } g_snprintf (x, sizeof (x), "%.0f%s", (size/divisor), xtra); @@ -327,12 +328,29 @@ size_trunc_len (char *buffer, int len, off_t size, int units) 1000000000}; static const char * const suffix [] = {"", "K", "M", "G", "T", "P", "E", "Z", "Y", NULL}; + static const char * const suffix_lc [] = + {"", "k", "m", "g", "t", "p", "e", "z", "y", NULL}; int j = 0; + int size_remain; /* Don't print more than 9 digits - use suffix. */ if (len == 0 || len > 9) len = 9; + /* + * recalculate from 1024 base to 1000 base if units>0 + * We can't just multiply by 1024 - that might cause overflow + * if off_t type is too small + */ + if (units && kilobyte_si) { + for (j = 0; j < units; j++) { + size_remain=((size % 125)*1024)/1000; /* size mod 125, recalculated */ + size = size / 125; /* 128/125 = 1024/1000 */ + size = size * 128; /* This will convert size from multiple of 1024 to multiple of 1000 */ + size += size_remain; /* Re-add remainder lost by division/multiplication */ + } + } + for (j = units; suffix [j] != NULL; j++) { if (size == 0) { if (j == units) { @@ -343,17 +361,21 @@ size_trunc_len (char *buffer, int len, off_t size, int units) /* Use "~K" or just "K" if len is 1. Use "B" for bytes. */ g_snprintf (buffer, len + 1, (len > 1) ? "~%s" : "%s", - (j > 1) ? suffix[j - 1] : "B"); + (j > 1) ? (kilobyte_si ? suffix_lc[j - 1] : suffix[j - 1]) : "B"); break; } if (size < power10 [len - (j > 0)]) { - g_snprintf (buffer, len + 1, "%lu%s", (unsigned long) size, suffix[j]); + g_snprintf (buffer, len + 1, "%lu%s", (unsigned long) size, kilobyte_si ? suffix_lc[j] : suffix[j]); break; } - /* Powers of 1024, with rounding. */ - size = (size + 512) >> 10; + /* Powers of 1000 or 1024, with rounding. */ + if (kilobyte_si) { + size = (size + 500) / 1000; + } else { + size = (size + 512) >> 10; + } } } -- 2.11.4.GIT