Author: brane
Date: Sun Nov 25 23:22:20 2018
New Revision: 1847443
URL: http://svn.apache.org/viewvc?rev=1847443&view=rev
Log:
Teach 'svn info' to show human-readable file sizes.
* subversion/svn/cl.h (svn_cl__get_base2_unit_file_size): New prototype.
* subversion/svn/filesize.c: New file.
(svn_cl__get_base2_unit_file_size): Implement. Moved here from list-cmd.c.
* subversion/svn/list-cmd.c: Remove unused includes.
(get_human_readable_size): Remove. Implementation moved to filesize.c.
(print_dirent): Use svn_cl__get_base2_unit_file_size().
* subversion/svn/info-cmd.c
(print_info_baton_t): New member 'human_readable'.
(print_info): Optionally print human-readable file sizes.
(svn_cl__info): Handle option --human-readable.
* subversion/svn/svn.c (svn_cl__cmd_table): Add -H to 'svn info'.
Added:
subversion/trunk/subversion/svn/filesize.c (with props)
Modified:
subversion/trunk/subversion/svn/cl.h
subversion/trunk/subversion/svn/info-cmd.c
subversion/trunk/subversion/svn/list-cmd.c
subversion/trunk/subversion/svn/svn.c
Modified: subversion/trunk/subversion/svn/cl.h
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/cl.h?rev=1847443&r1=1847442&r2=1847443&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/cl.h (original)
+++ subversion/trunk/subversion/svn/cl.h Sun Nov 25 23:22:20 2018
@@ -32,6 +32,7 @@
#include <apr_tables.h>
#include <apr_getopt.h>
+#include "svn_types.h"
#include "svn_wc.h"
#include "svn_client.h"
#include "svn_string.h"
@@ -722,6 +723,16 @@ svn_cl__node_kind_str_xml(svn_node_kind_
const char *
svn_cl__node_kind_str_human_readable(svn_node_kind_t kind);
+/* Return the size of a file, formatted to 3 colums in base-2 units.
+ if LONG_UNITS is TRUE, unit suffixes will be the whole SI symbol,
+ e.g., KiB, MiB, etc; otherwise only the first letters will be used.
+
+ File sizes are never negative, so we don't handle that case other than
+ making sure that the scale adjustment will work. */
+const char *
+svn_cl__get_base2_unit_file_size(svn_filesize_t size,
+ svn_boolean_t long_units,
+ apr_pool_t *result_pool);
/** Provides an XML name for a given OPERATION.
* Note: POOL is currently not used.
Added: subversion/trunk/subversion/svn/filesize.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/filesize.c?rev=1847443&view=auto
==============================================================================
--- subversion/trunk/subversion/svn/filesize.c (added)
+++ subversion/trunk/subversion/svn/filesize.c Sun Nov 25 23:22:20 2018
@@ -0,0 +1,118 @@
+/*
+ * filesize.c -- Utilities for displaying file sizes
+ *
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ */
+
+
+/*** Includes. ***/
+
+#include <assert.h>
+#include <math.h>
+#include <stdio.h>
+
+#include <apr_strings.h>
+
+#include "cl.h"
+
+
+/*** Code. ***/
+
+const char *
+svn_cl__get_base2_unit_file_size(svn_filesize_t size,
+ svn_boolean_t long_units,
+ apr_pool_t *result_pool)
+{
+ static const struct
+ {
+ svn_filesize_t mask;
+ const char *suffix;
+ const char *short_suffix;
+ }
+ order[] =
+ {
+ {APR_INT64_C(0x0000000000000000), " B", "B"}, /* byte */
+ {APR_INT64_C(0x00000000000003FF), " KiB", "K"}, /* kibi */
+ {APR_INT64_C(0x00000000000FFFFF), " MiB", "M"}, /* mibi */
+ {APR_INT64_C(0x000000003FFFFFFF), " GiB", "G"}, /* gibi */
+ {APR_INT64_C(0x000000FFFFFFFFFF), " TiB", "T"}, /* tibi */
+ {APR_INT64_C(0x0003FFFFFFFFFFFF), " EiB", "E"}, /* exbi */
+ {APR_INT64_C(0x0FFFFFFFFFFFFFFF), " PiB", "P"} /* pibi */
+ };
+ static const apr_size_t order_size = sizeof(order) / sizeof(order[0]);
+
+ const svn_filesize_t abs_size = ((size < 0) ? -size : size);
+ double human_readable_size;
+
+ /* Find the size mask for the (absolute) file size. It would be sexy to
+ do a binary search here, but with only 7 elements in the array ... */
+ apr_size_t index = order_size;
+ while (index > 0)
+ {
+ --index;
+ if (abs_size > order[index].mask)
+ break;
+ }
+
+ /* Adjust the size to the given order of magnitude.
+
+ This is division by (order[index].mask + 1), which is the base-2^10
+ magnitude of the size; and that is the same as an arithmetic right
+ shift by (index * 10) bits. But we split it into an integer and a
+ floating-point division, so that we don't overflow the mantissa at
+ very large file sizes. */
+ ;
+ if ((abs_size >> 10 * index) > 999)
+ {
+ /* This assertion should never fail, because we only have 4 binary
+ digits in the petabyte range and so the number of petabytes can't
+ be large enough to enter this conditional block. */
+ assert(index < order_size - 1);
+ ++index;
+ }
+ human_readable_size = (index == 0 ? (double)size
+ : (size >> 3 * index) / 128.0 / index);
+
+ /* NOTE: We want to display a locale-specific decimal sepratator, but
+ APR's formatter completely ignores the locale. So we use the
+ good, old, standard, *dangerous* sprintf() to format the size.
+
+ But, on the brigt side, we've just made sure that the number has
+ no more than 3 non-fractional digits. So the call to sprintf()
+ here should be safe. */
+ {
+ const char *const suffix = (long_units ? order[index].suffix
+ : order[index].short_suffix);
+
+ /* 3 digits (or 2 digits and 1 decimal separator)
+ + 1 negative sign (which should not appear under normal circumstances)
+ + 1 nul terminator
+ ---
+ = 5 characters of space needed in the buffer. */
+ char buffer[8];
+
+ /* When the adjusted size has only one significant digit left of the
+ decimal point, show tenths of a unit, too. */
+ sprintf(buffer, "%.*f",
+ fabs(human_readable_size) < 10.0 ? 1 : 0,
+ human_readable_size);
+ return apr_pstrcat(result_pool, buffer, suffix, SVN_VA_NULL);
+ }
+}
Propchange: subversion/trunk/subversion/svn/filesize.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: subversion/trunk/subversion/svn/info-cmd.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/info-cmd.c?rev=1847443&r1=1847442&r2=1847443&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/info-cmd.c (original)
+++ subversion/trunk/subversion/svn/info-cmd.c Sun Nov 25 23:22:20 2018
@@ -421,6 +421,9 @@ typedef struct print_info_baton_t
/* Did we already print a line of output? */
svn_boolean_t start_new_line;
+ /* Are we going to print human-readable sizes? */
+ svn_boolean_t human_readable;
+
/* The client context. */
svn_client_ctx_t *ctx;
} print_info_baton_t;
@@ -763,9 +766,15 @@ print_info(void *baton,
}
if (info->kind == svn_node_file && info->size != SVN_INVALID_FILESIZE)
- SVN_ERR(svn_cmdline_printf(pool, _("Size in Repository: %s\n"),
- apr_psprintf(pool, "%" SVN_FILESIZE_T_FMT,
- info->size)));
+ {
+ const char *const sizestr =
+ (receiver_baton->human_readable
+ ? svn_cl__get_base2_unit_file_size(info->size, TRUE, pool)
+ : apr_psprintf(pool, "%" SVN_FILESIZE_T_FMT,
+ info->size));
+ SVN_ERR(svn_cmdline_printf(pool, _("Size in Repository: %s\n"),
+ sizestr));
+ }
if (info->wc_info)
{
@@ -1262,6 +1271,10 @@ svn_cl__info(apr_getopt_t *os,
return svn_error_create(
SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
_("--no-newline is not valid in --xml mode"));
+ if (opt_state->human_readable)
+ return svn_error_create(
+ SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+ _("--human-readable is not valid in --xml mode"));
/* If output is not incremental, output the XML header and wrap
everything in a top-level element. This makes the output in
@@ -1277,6 +1290,10 @@ svn_cl__info(apr_getopt_t *os,
return svn_error_create(
SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
_("--incremental is only valid in --xml mode"));
+ if (opt_state->human_readable)
+ return svn_error_create(
+ SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+ _("--human-readable is not valid with --show-item"));
receiver_baton.multiple_targets = (opt_state->depth > svn_depth_empty
|| targets->nelts > 1);
@@ -1292,6 +1309,7 @@ svn_cl__info(apr_getopt_t *os,
else
{
receiver = print_info;
+ receiver_baton.human_readable = opt_state->human_readable;
if (opt_state->incremental)
return svn_error_create(
Modified: subversion/trunk/subversion/svn/list-cmd.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/list-cmd.c?rev=1847443&r1=1847442&r2=1847443&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/list-cmd.c (original)
+++ subversion/trunk/subversion/svn/list-cmd.c Sun Nov 25 23:22:20 2018
@@ -21,10 +21,6 @@
* ====================================================================
*/
-#include <assert.h>
-#include <math.h>
-#include <stdio.h>
-
#include "svn_cmdline.h"
#include "svn_client.h"
#include "svn_error.h"
@@ -74,85 +70,6 @@ static const apr_uint32_t print_dirent_f
SVN_DIRENT_KIND | SVN_DIRENT_SIZE | SVN_DIRENT_TIME |
SVN_DIRENT_CREATED_REV | SVN_DIRENT_LAST_AUTHOR);
-/* Converts a file size to human-readable form with base-2 unit suffix.
- File sizes are never negative, so we don't handle that case other than
- making sure that the scale adjustment will work. */
-static const char *
-get_human_readable_size(svn_filesize_t size, apr_pool_t *scratch_pool)
-{
- static const struct
- {
- svn_filesize_t mask;
- char suffix;
- }
- order[] =
- {
- {APR_INT64_C(0x0000000000000000), 'B'}, /* byte */
- {APR_INT64_C(0x00000000000003FF), 'K'}, /* kibi */
- {APR_INT64_C(0x00000000000FFFFF), 'M'}, /* mibi */
- {APR_INT64_C(0x000000003FFFFFFF), 'G'}, /* gibi */
- {APR_INT64_C(0x000000FFFFFFFFFF), 'T'}, /* tibi */
- {APR_INT64_C(0x0003FFFFFFFFFFFF), 'E'}, /* exbi */
- {APR_INT64_C(0x0FFFFFFFFFFFFFFF), 'P'} /* pibi */
- };
- static const apr_size_t order_size = sizeof(order) / sizeof(order[0]);
-
- const svn_filesize_t abs_size = ((size < 0) ? -size : size);
- double human_readable_size;
-
- /* Find the size mask for the (absolute) file size. It would be sexy to
- do a binary search here, but with only 7 elements in the array ... */
- apr_size_t index = order_size;
- while (index > 0)
- {
- --index;
- if (abs_size > order[index].mask)
- break;
- }
-
- /* Adjust the size to the given order of magnitude.
-
- This is division by (order[index].mask + 1), which is the base-2^10
- magnitude of the size; and that is the same as an arithmetic right
- shift by (index * 10) bits. But we split it into an integer and a
- floating-point division, so that we don't overflow the mantissa at
- very large file sizes. */
- ;
- if ((abs_size >> 10 * index) > 999)
- {
- /* This assertion should never fail, because we only have 4 binary
- digits in the petabyte range and so the number of petabytes can't
- be large enough to enter this conditional block. */
- assert(index < order_size - 1);
- ++index;
- }
- human_readable_size = (index == 0 ? (double)size
- : (size >> 3 * index) / 128.0 / index);
-
- /* NOTE: We want to display a locale-specific decimal sepratator, but
- APR's formatter completely ignores the locale. So we use the
- good, old, standard, *dangerous* sprintf() to format the size.
-
- But, on the brigt side, we've just made sure that the number has
- no more than 3 non-fractional digits. So the call to sprintf()
- here should be safe. */
- {
- /* 3 digits (or 2 digits and 1 decimal separator)
- + 1 unit suffix
- + 1 negative sign (which should not appear under normal circumstances)
- + 1 nul terminator
- ---
- = 6 characters of space needed in the buffer. */
- char buffer[8];
-
- /* When the adjusted size has only one significant digit left of the
- decimal point, show tenths of a unit, too. */
- sprintf(buffer, "%.*f%c",
- fabs(human_readable_size) < 10.0 ? 1 : 0,
- human_readable_size, order[index].suffix);
- return apr_pstrdup(scratch_pool, buffer);
- }
-}
/* This implements the svn_client_list_func2_t API, printing a single
directory entry in text format. */
@@ -265,7 +182,8 @@ print_dirent(void *baton,
if (dirent->kind == svn_node_file)
{
if (pb->human_readable)
- sizestr = get_human_readable_size(dirent->size, scratch_pool);
+ sizestr = svn_cl__get_base2_unit_file_size(dirent->size, FALSE,
+ scratch_pool);
else
sizestr = apr_psprintf(scratch_pool, "%" SVN_FILESIZE_T_FMT,
dirent->size);
Modified: subversion/trunk/subversion/svn/svn.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/svn.c?rev=1847443&r1=1847442&r2=1847443&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/svn.c (original)
+++ subversion/trunk/subversion/svn/svn.c Sun Nov 25 23:22:20 2018
@@ -859,9 +859,16 @@ const svn_opt_subcommand_desc3_t svn_cl_
" EXPERIMENTAL:\n"
" With --x-viewspec, print the working copy layout.\n"
)},
- {'r', 'R', opt_depth, opt_targets, opt_incremental, opt_xml,
+ {'r', 'R', 'H', opt_depth, opt_targets, opt_incremental, opt_xml,
opt_changelist, opt_include_externals, opt_show_item, opt_no_newline,
- opt_viewspec}
+ opt_viewspec},
+ {{'H', N_("show file sizes with base-2 unit suffixes\n"
+ " "
+ "(Byte, Kilobyte, Megabyte, Gigabyte, Terabyte\n"
+ " "
+ "and Petabyte), limiting the number of digits\n"
+ " "
+ "to three or less")}}
},
{ "list", svn_cl__list, {"ls"},