You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by br...@apache.org on 2018/11/27 11:13:27 UTC

svn commit: r1847527 - in /subversion/trunk/subversion: svn/cl.h svn/filesize.c svn/info-cmd.c svn/list-cmd.c svn/svn.c tests/cmdline/info_tests.py

Author: brane
Date: Tue Nov 27 11:13:27 2018
New Revision: 1847527

URL: http://svn.apache.org/viewvc?rev=1847527&view=rev
Log:
Consolidate file size formatting for 'svn info' and 'svn list'.

* subversion/svn/cl.h
  (svn_cl__size_unit_t): Renamed and extended from svn_cl__unit_base_t.
  (svn_cl__opt_state_t): New field 'file_size_unit' replaces the
   'human_readable' flag. All users updated.
  (svn_cl__format_file_size): Renamed from svn_cl__get_unit_file_size.

* subversion/svn/filesize.c
  (get_base2_unit_file_size, get_base10_unit_file_size): Tweak some comments.
  (svn_cl__format_file_size): Renamed from svn_cl__get_unit_file_size.
   Also handle formatting for XML and for normal output.

* subversion/svn/info-cmd.c
  (print_info_baton_t): 'file_size_unit' replaces the 'human_readable' flag.
  (print_info_xml): Use svn_cl__format_file_size() in XML mode.
  (print_info): Use only svn_cl__format_file_size() for file sizes.
  (print_info_item): Likewise.
  (svn_cl__info): Allow unit-based file size output with --show-item.

* subversion/svn/list-cmd.c
  (print_baton): 'file_size_unit' replaces the 'human_readable' flag.
  (print_dirent): Use only svn_cl__format_file_size() for file sizes.
  (print_dirent_xml): Use svn_cl__format_file_size() in XML mode.
  (svn_cl__list): Update for changes to svn_cl__opt_state_t.

* subversion/svn/svn.c
  (sub_main): Handle the new file_size_unit field in svn_cl__opt_state_t.

* subversion/tests/cmdline/info_tests.py
  (info_item_size_repos): Add two new test modes.

Modified:
    subversion/trunk/subversion/svn/cl.h
    subversion/trunk/subversion/svn/filesize.c
    subversion/trunk/subversion/svn/info-cmd.c
    subversion/trunk/subversion/svn/list-cmd.c
    subversion/trunk/subversion/svn/svn.c
    subversion/trunk/subversion/tests/cmdline/info_tests.py

Modified: subversion/trunk/subversion/svn/cl.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/cl.h?rev=1847527&r1=1847526&r2=1847527&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/cl.h (original)
+++ subversion/trunk/subversion/svn/cl.h Tue Nov 27 11:13:27 2018
@@ -127,6 +127,16 @@ typedef enum svn_cl__show_revs_t {
 svn_cl__show_revs_t
 svn_cl__show_revs_from_word(const char *word);
 
+
+/* Unit tupes for file size conversion. */
+typedef enum svn_cl__size_unit_t
+  {
+    SVN_CL__SIZE_UNIT_NONE = 0,       /* Default, no conversion. */
+    SVN_CL__SIZE_UNIT_XML = -1,       /* Conversion for XML output. */
+    SVN_CL__SIZE_UNIT_BASE_10 = 1000, /* Use base-10 SI units. */
+    SVN_CL__SIZE_UNIT_BASE_2 = 1024   /* Use base-2 SI units. */
+  } svn_cl__size_unit_t;
+
 
 /*** Command dispatch. ***/
 
@@ -258,7 +268,7 @@ typedef struct svn_cl__opt_state_t
   svn_boolean_t adds_as_modification; /* update 'add vs add' no tree conflict */
   svn_boolean_t vacuum_pristines; /* remove unreferenced pristines */
   svn_boolean_t drop;             /* drop shelf after successful unshelve */
-  svn_boolean_t human_readable;   /* show human-readable output */
+  svn_cl__size_unit_t file_size_unit; /* file size format */
   enum svn_cl__viewspec_t {
       svn_cl__viewspec_unspecified = 0 /* default */,
       svn_cl__viewspec_classic,
@@ -723,15 +733,11 @@ svn_cl__node_kind_str_xml(svn_node_kind_
 const char *
 svn_cl__node_kind_str_human_readable(svn_node_kind_t kind);
 
-/* Supported unit bases for file size conversion. */
-typedef enum svn_cl__unit_base_t
-  {
-    SVN_CL__BASE_10_UNIT = 1000, /* Use base-10 SI units. */
-    SVN_CL__BASE_2_UNIT = 1024   /* Use base-2 SI units. */
-  } svn_cl__unit_base_t;
+/* Set *RESULT to the size of a file, formatted according to BASE.
+   For base-10 and base-2 units, the size is constrainsd to at most
+   three significant digits.
 
-/* Set *RESULT to the size of a file, formatted to 3 colums in BASE units.
-   if LONG_UNITS is TRUE, unit suffixes will be the whole SI symbol,
+   If LONG_UNITS is TRUE, any 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
@@ -739,11 +745,11 @@ typedef enum svn_cl__unit_base_t
 
    The result will be allocated from RESULT_POOL. */
 svn_error_t *
-svn_cl__get_unit_file_size(const char **result,
-                           svn_filesize_t size,
-                           svn_cl__unit_base_t base,
-                           svn_boolean_t long_units,
-                           apr_pool_t *result_pool);
+svn_cl__format_file_size(const char **result,
+                         svn_filesize_t size,
+                         svn_cl__size_unit_t base,
+                         svn_boolean_t long_units,
+                         apr_pool_t *result_pool);
 
 
 /** Provides an XML name for a given OPERATION.

Modified: subversion/trunk/subversion/svn/filesize.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/filesize.c?rev=1847527&r1=1847526&r2=1847527&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/filesize.c (original)
+++ subversion/trunk/subversion/svn/filesize.c Tue Nov 27 11:13:27 2018
@@ -129,12 +129,12 @@ get_base2_unit_file_size(svn_filesize_t
      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. */
+         digits in the petabyte (all right, "pibibyte") range and so the
+         number of petabytes can't be large enough to cause the program
+         flow to enter this conditional block. */
       assert(index < order_size - 1);
       ++index;
     }
@@ -160,6 +160,7 @@ get_base10_unit_file_size(svn_filesize_t
       {APR_INT64_C(      999999999999), " TB", "T"}, /* tera */
       {APR_INT64_C(   999999999999999), " EB", "E"}, /* exa  */
       {APR_INT64_C(999999999999999999), " PB", "P"}  /* peta */
+      /*         18446744073709551615 is the maximum value.  */
     };
   static const apr_size_t order_size = sizeof(order) / sizeof(order[0]);
 
@@ -179,7 +180,7 @@ get_base10_unit_file_size(svn_filesize_t
     human_readable_size = (double)size / (order[index].mask + 1);
   else
     {
-      /*                              [  Keep integer division here!  ] */
+      /*                             [   Keep integer division here!   ] */
       const double divisor = (double)((order[index].mask + 1) / 1000000);
       human_readable_size = (size / 1000000) / divisor;
       /*                    [   And here!  ] */
@@ -191,19 +192,24 @@ get_base10_unit_file_size(svn_filesize_t
 
 
 svn_error_t *
-svn_cl__get_unit_file_size(const char **result,
-                           svn_filesize_t size,
-                           svn_cl__unit_base_t base,
-                           svn_boolean_t long_units,
-                           apr_pool_t *result_pool)
+svn_cl__format_file_size(const char **result,
+                         svn_filesize_t size,
+                         svn_cl__size_unit_t base,
+                         svn_boolean_t long_units,
+                         apr_pool_t *result_pool)
 {
   switch (base)
     {
-    case SVN_CL__BASE_2_UNIT:
+    case SVN_CL__SIZE_UNIT_NONE:
+    case SVN_CL__SIZE_UNIT_XML:
+      *result = apr_psprintf(result_pool, "%" SVN_FILESIZE_T_FMT, size);
+      break;
+
+    case SVN_CL__SIZE_UNIT_BASE_2:
       *result = get_base2_unit_file_size(size, long_units, result_pool);
       break;
 
-    case SVN_CL__BASE_10_UNIT:
+    case SVN_CL__SIZE_UNIT_BASE_10:
       *result = get_base10_unit_file_size(size, long_units, result_pool);
       break;
 

Modified: subversion/trunk/subversion/svn/info-cmd.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/info-cmd.c?rev=1847527&r1=1847526&r2=1847527&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/info-cmd.c (original)
+++ subversion/trunk/subversion/svn/info-cmd.c Tue Nov 27 11:13:27 2018
@@ -421,8 +421,8 @@ 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;
+  /* Format for file sizes */
+  svn_cl__size_unit_t file_size_unit;
 
   /* The client context. */
   svn_client_ctx_t *ctx;
@@ -526,8 +526,10 @@ print_info_xml(void *baton,
   /* "<entry ...>" */
   if (info->kind == svn_node_file && info->size != SVN_INVALID_FILESIZE)
     {
-      const char *const size_str =
-        apr_psprintf(pool, "%" SVN_FILESIZE_T_FMT, info->size);
+      const char *size_str;
+      SVN_ERR(svn_cl__format_file_size(&size_str, info->size,
+                                       SVN_CL__SIZE_UNIT_XML,
+                                       FALSE, pool));
 
       svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "entry",
                             "path", path_str,
@@ -768,16 +770,9 @@ print_info(void *baton,
   if (info->kind == svn_node_file && info->size != SVN_INVALID_FILESIZE)
     {
       const char *sizestr;
-      if (receiver_baton->human_readable)
-        {
-          SVN_ERR(svn_cl__get_unit_file_size(&sizestr, info->size,
-                                             SVN_CL__BASE_2_UNIT,
-                                             TRUE, pool));
-        }
-      else
-        {
-          sizestr = apr_psprintf(pool, "%" SVN_FILESIZE_T_FMT, info->size);
-        }
+      SVN_ERR(svn_cl__format_file_size(&sizestr, info->size,
+                                       receiver_baton->file_size_unit,
+                                       TRUE, pool));
       SVN_ERR(svn_cmdline_printf(pool, _("Size in Repository: %s\n"),
                                  sizestr));
     }
@@ -1177,9 +1172,13 @@ print_info_item(void *baton,
               actual_target_path);
         }
 
-      SVN_ERR(print_info_item_string(
-                  apr_psprintf(pool, "%" SVN_FILESIZE_T_FMT, info->size),
-                  target_path, pool));
+      {
+        const char *sizestr;
+        SVN_ERR(svn_cl__format_file_size(&sizestr, info->size,
+                                         receiver_baton->file_size_unit,
+                                         TRUE, pool));
+        SVN_ERR(print_info_item_string(sizestr, target_path, pool));
+      }
       break;
 
     case info_item_revision:
@@ -1264,6 +1263,7 @@ svn_cl__info(apr_getopt_t *os,
   svn_opt_push_implicit_dot_target(targets, pool);
 
   receiver_baton.ctx = ctx;
+  receiver_baton.file_size_unit = opt_state->file_size_unit;
 
   if (opt_state->xml)
     {
@@ -1277,7 +1277,7 @@ 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)
+      if (opt_state->file_size_unit != SVN_CL__SIZE_UNIT_NONE)
         return svn_error_create(
             SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
             _("--human-readable is not valid in --xml mode"));
@@ -1296,10 +1296,6 @@ 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);
@@ -1315,7 +1311,6 @@ 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=1847527&r1=1847526&r2=1847527&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/list-cmd.c (original)
+++ subversion/trunk/subversion/svn/list-cmd.c Tue Nov 27 11:13:27 2018
@@ -42,7 +42,7 @@
 struct print_baton {
   svn_client_ctx_t *ctx;
   svn_boolean_t verbose;
-  svn_boolean_t human_readable;
+  svn_cl__size_unit_t file_size_unit;
 
   /* Keep track of the width of the author field. */
   int author_width;
@@ -137,7 +137,8 @@ print_dirent(void *baton,
       apr_status_t apr_err;
       apr_size_t size;
       char timestr[20];
-      const int sizewidth = (!pb->human_readable ? normal_size_width
+      const int sizewidth = (pb->file_size_unit == SVN_CL__SIZE_UNIT_NONE
+                             ? normal_size_width
                              : human_readable_size_width);
       const char *sizestr = "";
       const char *utf8_timestr;
@@ -178,20 +179,11 @@ print_dirent(void *baton,
             }
         }
 
-      /* The format of the size field depends on the --human-readable flag. */
       if (dirent->kind == svn_node_file)
         {
-          if (pb->human_readable)
-            {
-              SVN_ERR(svn_cl__get_unit_file_size(&sizestr, dirent->size,
-                                                 SVN_CL__BASE_2_UNIT,
-                                                 FALSE, scratch_pool));
-            }
-          else
-            {
-              sizestr = apr_psprintf(scratch_pool, "%" SVN_FILESIZE_T_FMT,
-                                     dirent->size);
-            }
+          SVN_ERR(svn_cl__format_file_size(&sizestr, dirent->size,
+                                           pb->file_size_unit,
+                                           FALSE, scratch_pool));
         }
 
       return svn_cmdline_printf
@@ -284,9 +276,11 @@ print_dirent_xml(void *baton,
 
   if (dirent->kind == svn_node_file)
     {
-      svn_cl__xml_tagged_cdata
-        (&sb, scratch_pool, "size",
-         apr_psprintf(scratch_pool, "%" SVN_FILESIZE_T_FMT, dirent->size));
+      const char *sizestr;
+      SVN_ERR(svn_cl__format_file_size(&sizestr, dirent->size,
+                                       SVN_CL__SIZE_UNIT_XML,
+                                       FALSE, scratch_pool));
+      svn_cl__xml_tagged_cdata(&sb, scratch_pool, "size", sizestr);
     }
 
   svn_xml_make_open_tag(&sb, scratch_pool, svn_xml_normal, "commit",
@@ -356,7 +350,7 @@ svn_cl__list(apr_getopt_t *os,
         return svn_error_create(
             SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
             _("--verbose is not valid in --xml mode"));
-      if (opt_state->human_readable)
+      if (opt_state->file_size_unit != SVN_CL__SIZE_UNIT_NONE)
         return svn_error_create(
             SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
             _("--human-readable is not valid in --xml mode"));
@@ -384,11 +378,17 @@ svn_cl__list(apr_getopt_t *os,
 
   pb.ctx = ctx;
   pb.verbose = opt_state->verbose;
-  pb.human_readable = opt_state->human_readable;
-  pb.author_width = (!pb.human_readable ? initial_author_width
-                     : initial_human_readable_author_width);
-  pb.max_author_width = (!pb.human_readable ? maximum_author_width
-                         : maximum_human_readable_author_width);
+  pb.file_size_unit = opt_state->file_size_unit;
+  if (pb.file_size_unit == SVN_CL__SIZE_UNIT_NONE)
+    {
+      pb.author_width = initial_author_width;
+      pb.max_author_width = maximum_author_width;
+    }
+  else
+    {
+      pb.author_width = initial_human_readable_author_width;
+      pb.max_author_width = maximum_human_readable_author_width;
+    }
 
   if (opt_state->depth == svn_depth_unknown)
     opt_state->depth = svn_depth_immediates;

Modified: subversion/trunk/subversion/svn/svn.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/svn.c?rev=1847527&r1=1847526&r2=1847527&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/svn.c (original)
+++ subversion/trunk/subversion/svn/svn.c Tue Nov 27 11:13:27 2018
@@ -2281,6 +2281,7 @@ sub_main(int *exit_code, int argc, const
   opt_state.set_depth = svn_depth_unknown;
   opt_state.accept_which = svn_cl__accept_unspecified;
   opt_state.show_revs = svn_cl__show_revs_invalid;
+  opt_state.file_size_unit = SVN_CL__SIZE_UNIT_NONE;
 
   /* No args?  Show usage. */
   if (argc <= 1)
@@ -2497,7 +2498,7 @@ sub_main(int *exit_code, int argc, const
         descend = FALSE;
         break;
       case 'H':
-        opt_state.human_readable = TRUE;
+        opt_state.file_size_unit = SVN_CL__SIZE_UNIT_BASE_2;
         break;
       case opt_depth:
         err = svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool);

Modified: subversion/trunk/subversion/tests/cmdline/info_tests.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/info_tests.py?rev=1847527&r1=1847526&r2=1847527&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/info_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/info_tests.py Tue Nov 27 11:13:27 2018
@@ -728,7 +728,7 @@ def info_item_size_wc_recursive(sbox):
 
 
 def info_item_size_repos(sbox):
-  "non-recursive '--show-item=repos-size' on file URL"
+  "non-recursive '--show-item=repos-size' on URL"
 
   sbox.build(read_only=True)
 
@@ -737,11 +737,24 @@ def info_item_size_repos(sbox):
     'info', '--show-item=repos-size',
     sbox.repo_url + "/iota")
 
+  # Same, but without the newline.
   svntest.actions.run_and_verify_svn(
     "25", [],
     'info', '--show-item=repos-size', '--no-newline',
     sbox.repo_url + "/iota")
 
+  # Same, but with "human-readable" output.
+  svntest.actions.run_and_verify_svn(
+    "25 B", [],
+    'info', '--show-item=repos-size', '--human-readable',
+    sbox.repo_url + "/iota")
+
+  # No output when the URL is a directory.
+  svntest.actions.run_and_verify_svn(
+    [], [],
+    'info', '--show-item=repos-size',
+    sbox.repo_url)
+
 
 def info_item_size_repos_recursive(sbox):
   "recursive '--show-item=repos-size' on dir URL"