Blame lib/human.c

Packit 8f70b4
/* human.c -- print human readable file size
Packit 8f70b4
Packit 8f70b4
   Copyright (C) 1996-2007, 2009-2018 Free Software Foundation, Inc.
Packit 8f70b4
Packit 8f70b4
   This program is free software: you can redistribute it and/or modify
Packit 8f70b4
   it under the terms of the GNU General Public License as published by
Packit 8f70b4
   the Free Software Foundation; either version 3 of the License, or
Packit 8f70b4
   (at your option) any later version.
Packit 8f70b4
Packit 8f70b4
   This program is distributed in the hope that it will be useful,
Packit 8f70b4
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 8f70b4
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 8f70b4
   GNU General Public License for more details.
Packit 8f70b4
Packit 8f70b4
   You should have received a copy of the GNU General Public License
Packit 8f70b4
   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
Packit 8f70b4
Packit 8f70b4
/* Written by Paul Eggert and Larry McVoy.  */
Packit 8f70b4
Packit 8f70b4
#include <config.h>
Packit 8f70b4
Packit 8f70b4
#include "human.h"
Packit 8f70b4
Packit 8f70b4
#include <locale.h>
Packit 8f70b4
#include <stdio.h>
Packit 8f70b4
#include <stdlib.h>
Packit 8f70b4
#include <string.h>
Packit 8f70b4
Packit 8f70b4
#include <argmatch.h>
Packit 8f70b4
#include <error.h>
Packit 8f70b4
#include <intprops.h>
Packit 8f70b4
Packit 8f70b4
/* The maximum length of a suffix like "KiB".  */
Packit 8f70b4
#define HUMAN_READABLE_SUFFIX_LENGTH_MAX 3
Packit 8f70b4
Packit 8f70b4
static const char power_letter[] =
Packit 8f70b4
{
Packit 8f70b4
  0,    /* not used */
Packit 8f70b4
  'K',  /* kibi ('k' for kilo is a special case) */
Packit 8f70b4
  'M',  /* mega or mebi */
Packit 8f70b4
  'G',  /* giga or gibi */
Packit 8f70b4
  'T',  /* tera or tebi */
Packit 8f70b4
  'P',  /* peta or pebi */
Packit 8f70b4
  'E',  /* exa or exbi */
Packit 8f70b4
  'Z',  /* zetta or 2**70 */
Packit 8f70b4
  'Y'   /* yotta or 2**80 */
Packit 8f70b4
};
Packit 8f70b4
Packit 8f70b4
Packit 8f70b4
/* If INEXACT_STYLE is not human_round_to_nearest, and if easily
Packit 8f70b4
   possible, adjust VALUE according to the style.  */
Packit 8f70b4
Packit 8f70b4
static long double
Packit 8f70b4
adjust_value (int inexact_style, long double value)
Packit 8f70b4
{
Packit 8f70b4
  /* Do not use the floorl or ceill functions, as that would mean
Packit 8f70b4
     checking for their presence and possibly linking with the
Packit 8f70b4
     standard math library, which is a porting pain.  So leave the
Packit 8f70b4
     value alone if it is too large to easily round.  */
Packit 8f70b4
  if (inexact_style != human_round_to_nearest && value < UINTMAX_MAX)
Packit 8f70b4
    {
Packit 8f70b4
      uintmax_t u = value;
Packit 8f70b4
      value = u + (inexact_style == human_ceiling && u != value);
Packit 8f70b4
    }
Packit 8f70b4
Packit 8f70b4
  return value;
Packit 8f70b4
}
Packit 8f70b4
Packit 8f70b4
/* Group the digits of NUMBER according to the grouping rules of the
Packit 8f70b4
   current locale.  NUMBER contains NUMBERLEN digits.  Modify the
Packit 8f70b4
   bytes pointed to by NUMBER in place, subtracting 1 from NUMBER for
Packit 8f70b4
   each byte inserted.  Return the starting address of the modified
Packit 8f70b4
   number.
Packit 8f70b4
Packit 8f70b4
   To group the digits, use GROUPING and THOUSANDS_SEP as in 'struct
Packit 8f70b4
   lconv' from <locale.h>.  */
Packit 8f70b4
Packit 8f70b4
static char *
Packit 8f70b4
group_number (char *number, size_t numberlen,
Packit 8f70b4
              char const *grouping, char const *thousands_sep)
Packit 8f70b4
{
Packit 8f70b4
  register char *d;
Packit 8f70b4
  size_t grouplen = SIZE_MAX;
Packit 8f70b4
  size_t thousands_seplen = strlen (thousands_sep);
Packit 8f70b4
  size_t i = numberlen;
Packit 8f70b4
Packit 8f70b4
  /* The maximum possible value for NUMBERLEN is the number of digits
Packit 8f70b4
     in the square of the largest uintmax_t, so double the size needed.  */
Packit 8f70b4
  char buf[2 * INT_STRLEN_BOUND (uintmax_t) + 1];
Packit 8f70b4
Packit 8f70b4
  memcpy (buf, number, numberlen);
Packit 8f70b4
  d = number + numberlen;
Packit 8f70b4
Packit 8f70b4
  for (;;)
Packit 8f70b4
    {
Packit 8f70b4
      unsigned char g = *grouping;
Packit 8f70b4
Packit 8f70b4
      if (g)
Packit 8f70b4
        {
Packit 8f70b4
          grouplen = g < CHAR_MAX ? g : i;
Packit 8f70b4
          grouping++;
Packit 8f70b4
        }
Packit 8f70b4
Packit 8f70b4
      if (i < grouplen)
Packit 8f70b4
        grouplen = i;
Packit 8f70b4
Packit 8f70b4
      d -= grouplen;
Packit 8f70b4
      i -= grouplen;
Packit 8f70b4
      memcpy (d, buf + i, grouplen);
Packit 8f70b4
      if (i == 0)
Packit 8f70b4
        return d;
Packit 8f70b4
Packit 8f70b4
      d -= thousands_seplen;
Packit 8f70b4
      memcpy (d, thousands_sep, thousands_seplen);
Packit 8f70b4
    }
Packit 8f70b4
}
Packit 8f70b4
Packit 8f70b4
/* Convert N to a human readable format in BUF, using the options OPTS.
Packit 8f70b4
Packit 8f70b4
   N is expressed in units of FROM_BLOCK_SIZE.  FROM_BLOCK_SIZE must
Packit 8f70b4
   be nonnegative.
Packit 8f70b4
Packit 8f70b4
   Use units of TO_BLOCK_SIZE in the output number.  TO_BLOCK_SIZE
Packit 8f70b4
   must be positive.
Packit 8f70b4
Packit 8f70b4
   Use (OPTS & (human_round_to_nearest | human_floor | human_ceiling))
Packit 8f70b4
   to determine whether to take the ceiling or floor of any result
Packit 8f70b4
   that cannot be expressed exactly.
Packit 8f70b4
Packit 8f70b4
   If (OPTS & human_group_digits), group the thousands digits
Packit 8f70b4
   according to the locale, e.g., "1,000,000" in an American English
Packit 8f70b4
   locale.
Packit 8f70b4
Packit 8f70b4
   If (OPTS & human_autoscale), deduce the output block size
Packit 8f70b4
   automatically; TO_BLOCK_SIZE must be 1 but it has no effect on the
Packit 8f70b4
   output.  Use powers of 1024 if (OPTS & human_base_1024), and powers
Packit 8f70b4
   of 1000 otherwise.  For example, assuming powers of 1024, 8500
Packit 8f70b4
   would be converted to 8.3, 133456345 to 127, 56990456345 to 53, and
Packit 8f70b4
   so on.  Numbers smaller than the power aren't modified.
Packit 8f70b4
   human_autoscale is normally used together with human_SI.
Packit 8f70b4
Packit 8f70b4
   If (OPTS & human_space_before_unit), use a space to separate the
Packit 8f70b4
   number from any suffix that is appended as described below.
Packit 8f70b4
Packit 8f70b4
   If (OPTS & human_SI), append an SI prefix indicating which power is
Packit 8f70b4
   being used.  If in addition (OPTS & human_B), append "B" (if base
Packit 8f70b4
   1000) or "iB" (if base 1024) to the SI prefix.  When ((OPTS &
Packit 8f70b4
   human_SI) && ! (OPTS & human_autoscale)), TO_BLOCK_SIZE must be a
Packit 8f70b4
   power of 1024 or of 1000, depending on (OPTS &
Packit 8f70b4
   human_base_1024).  */
Packit 8f70b4
Packit 8f70b4
char *
Packit 8f70b4
human_readable (uintmax_t n, char *buf, int opts,
Packit 8f70b4
                uintmax_t from_block_size, uintmax_t to_block_size)
Packit 8f70b4
{
Packit 8f70b4
  int inexact_style =
Packit 8f70b4
    opts & (human_round_to_nearest | human_floor | human_ceiling);
Packit 8f70b4
  unsigned int base = opts & human_base_1024 ? 1024 : 1000;
Packit 8f70b4
  uintmax_t amt;
Packit 8f70b4
  int tenths;
Packit 8f70b4
  int exponent = -1;
Packit 8f70b4
  int exponent_max = sizeof power_letter - 1;
Packit 8f70b4
  char *p;
Packit 8f70b4
  char *psuffix;
Packit 8f70b4
  char const *integerlim;
Packit 8f70b4
Packit 8f70b4
  /* 0 means adjusted N == AMT.TENTHS;
Packit 8f70b4
     1 means AMT.TENTHS < adjusted N < AMT.TENTHS + 0.05;
Packit 8f70b4
     2 means adjusted N == AMT.TENTHS + 0.05;
Packit 8f70b4
     3 means AMT.TENTHS + 0.05 < adjusted N < AMT.TENTHS + 0.1.  */
Packit 8f70b4
  int rounding;
Packit 8f70b4
Packit 8f70b4
  char const *decimal_point = ".";
Packit 8f70b4
  size_t decimal_pointlen = 1;
Packit 8f70b4
  char const *grouping = "";
Packit 8f70b4
  char const *thousands_sep = "";
Packit 8f70b4
  struct lconv const *l = localeconv ();
Packit 8f70b4
  size_t pointlen = strlen (l->decimal_point);
Packit 8f70b4
  if (0 < pointlen && pointlen <= MB_LEN_MAX)
Packit 8f70b4
    {
Packit 8f70b4
      decimal_point = l->decimal_point;
Packit 8f70b4
      decimal_pointlen = pointlen;
Packit 8f70b4
    }
Packit 8f70b4
  grouping = l->grouping;
Packit 8f70b4
  if (strlen (l->thousands_sep) <= MB_LEN_MAX)
Packit 8f70b4
    thousands_sep = l->thousands_sep;
Packit 8f70b4
Packit 8f70b4
  /* Leave room for a trailing space and following suffix.  */
Packit 8f70b4
  psuffix = buf + LONGEST_HUMAN_READABLE - 1 - HUMAN_READABLE_SUFFIX_LENGTH_MAX;
Packit 8f70b4
  p = psuffix;
Packit 8f70b4
Packit 8f70b4
  /* Adjust AMT out of FROM_BLOCK_SIZE units and into TO_BLOCK_SIZE
Packit 8f70b4
     units.  If this can be done exactly with integer arithmetic, do
Packit 8f70b4
     not use floating point operations.  */
Packit 8f70b4
  if (to_block_size <= from_block_size)
Packit 8f70b4
    {
Packit 8f70b4
      if (from_block_size % to_block_size == 0)
Packit 8f70b4
        {
Packit 8f70b4
          uintmax_t multiplier = from_block_size / to_block_size;
Packit 8f70b4
          amt = n * multiplier;
Packit 8f70b4
          if (amt / multiplier == n)
Packit 8f70b4
            {
Packit 8f70b4
              tenths = 0;
Packit 8f70b4
              rounding = 0;
Packit 8f70b4
              goto use_integer_arithmetic;
Packit 8f70b4
            }
Packit 8f70b4
        }
Packit 8f70b4
    }
Packit 8f70b4
  else if (from_block_size != 0 && to_block_size % from_block_size == 0)
Packit 8f70b4
    {
Packit 8f70b4
      uintmax_t divisor = to_block_size / from_block_size;
Packit 8f70b4
      uintmax_t r10 = (n % divisor) * 10;
Packit 8f70b4
      uintmax_t r2 = (r10 % divisor) * 2;
Packit 8f70b4
      amt = n / divisor;
Packit 8f70b4
      tenths = r10 / divisor;
Packit 8f70b4
      rounding = r2 < divisor ? 0 < r2 : 2 + (divisor < r2);
Packit 8f70b4
      goto use_integer_arithmetic;
Packit 8f70b4
    }
Packit 8f70b4
Packit 8f70b4
  {
Packit 8f70b4
    /* Either the result cannot be computed easily using uintmax_t,
Packit 8f70b4
       or from_block_size is zero.  Fall back on floating point.
Packit 8f70b4
       FIXME: This can yield answers that are slightly off.  */
Packit 8f70b4
Packit 8f70b4
    long double dto_block_size = to_block_size;
Packit 8f70b4
    long double damt = n * (from_block_size / dto_block_size);
Packit 8f70b4
    size_t buflen;
Packit 8f70b4
    size_t nonintegerlen;
Packit 8f70b4
Packit 8f70b4
    if (! (opts & human_autoscale))
Packit 8f70b4
      {
Packit 8f70b4
        sprintf (buf, "%.0Lf", adjust_value (inexact_style, damt));
Packit 8f70b4
        buflen = strlen (buf);
Packit 8f70b4
        nonintegerlen = 0;
Packit 8f70b4
      }
Packit 8f70b4
    else
Packit 8f70b4
      {
Packit 8f70b4
        long double e = 1;
Packit 8f70b4
        exponent = 0;
Packit 8f70b4
Packit 8f70b4
        do
Packit 8f70b4
          {
Packit 8f70b4
            e *= base;
Packit 8f70b4
            exponent++;
Packit 8f70b4
          }
Packit 8f70b4
        while (e * base <= damt && exponent < exponent_max);
Packit 8f70b4
Packit 8f70b4
        damt /= e;
Packit 8f70b4
Packit 8f70b4
        sprintf (buf, "%.1Lf", adjust_value (inexact_style, damt));
Packit 8f70b4
        buflen = strlen (buf);
Packit 8f70b4
        nonintegerlen = decimal_pointlen + 1;
Packit 8f70b4
Packit 8f70b4
        if (1 + nonintegerlen + ! (opts & human_base_1024) < buflen
Packit 8f70b4
            || ((opts & human_suppress_point_zero)
Packit 8f70b4
                && buf[buflen - 1] == '0'))
Packit 8f70b4
          {
Packit 8f70b4
            sprintf (buf, "%.0Lf",
Packit 8f70b4
                     adjust_value (inexact_style, damt * 10) / 10);
Packit 8f70b4
            buflen = strlen (buf);
Packit 8f70b4
            nonintegerlen = 0;
Packit 8f70b4
          }
Packit 8f70b4
      }
Packit 8f70b4
Packit 8f70b4
    p = psuffix - buflen;
Packit 8f70b4
    memmove (p, buf, buflen);
Packit 8f70b4
    integerlim = p + buflen - nonintegerlen;
Packit 8f70b4
  }
Packit 8f70b4
  goto do_grouping;
Packit 8f70b4
Packit 8f70b4
 use_integer_arithmetic:
Packit 8f70b4
  {
Packit 8f70b4
    /* The computation can be done exactly, with integer arithmetic.
Packit 8f70b4
Packit 8f70b4
       Use power of BASE notation if requested and if adjusted AMT is
Packit 8f70b4
       large enough.  */
Packit 8f70b4
Packit 8f70b4
    if (opts & human_autoscale)
Packit 8f70b4
      {
Packit 8f70b4
        exponent = 0;
Packit 8f70b4
Packit 8f70b4
        if (base <= amt)
Packit 8f70b4
          {
Packit 8f70b4
            do
Packit 8f70b4
              {
Packit 8f70b4
                unsigned int r10 = (amt % base) * 10 + tenths;
Packit 8f70b4
                unsigned int r2 = (r10 % base) * 2 + (rounding >> 1);
Packit 8f70b4
                amt /= base;
Packit 8f70b4
                tenths = r10 / base;
Packit 8f70b4
                rounding = (r2 < base
Packit 8f70b4
                            ? (r2 + rounding) != 0
Packit 8f70b4
                            : 2 + (base < r2 + rounding));
Packit 8f70b4
                exponent++;
Packit 8f70b4
              }
Packit 8f70b4
            while (base <= amt && exponent < exponent_max);
Packit 8f70b4
Packit 8f70b4
            if (amt < 10)
Packit 8f70b4
              {
Packit 8f70b4
                if (inexact_style == human_round_to_nearest
Packit 8f70b4
                    ? 2 < rounding + (tenths & 1)
Packit 8f70b4
                    : inexact_style == human_ceiling && 0 < rounding)
Packit 8f70b4
                  {
Packit 8f70b4
                    tenths++;
Packit 8f70b4
                    rounding = 0;
Packit 8f70b4
Packit 8f70b4
                    if (tenths == 10)
Packit 8f70b4
                      {
Packit 8f70b4
                        amt++;
Packit 8f70b4
                        tenths = 0;
Packit 8f70b4
                      }
Packit 8f70b4
                  }
Packit 8f70b4
Packit 8f70b4
                if (amt < 10
Packit 8f70b4
                    && (tenths || ! (opts & human_suppress_point_zero)))
Packit 8f70b4
                  {
Packit 8f70b4
                    *--p = '0' + tenths;
Packit 8f70b4
                    p -= decimal_pointlen;
Packit 8f70b4
                    memcpy (p, decimal_point, decimal_pointlen);
Packit 8f70b4
                    tenths = rounding = 0;
Packit 8f70b4
                  }
Packit 8f70b4
              }
Packit 8f70b4
          }
Packit 8f70b4
      }
Packit 8f70b4
Packit 8f70b4
    if (inexact_style == human_round_to_nearest
Packit 8f70b4
        ? 5 < tenths + (0 < rounding + (amt & 1))
Packit 8f70b4
        : inexact_style == human_ceiling && 0 < tenths + rounding)
Packit 8f70b4
      {
Packit 8f70b4
        amt++;
Packit 8f70b4
Packit 8f70b4
        if ((opts & human_autoscale)
Packit 8f70b4
            && amt == base && exponent < exponent_max)
Packit 8f70b4
          {
Packit 8f70b4
            exponent++;
Packit 8f70b4
            if (! (opts & human_suppress_point_zero))
Packit 8f70b4
              {
Packit 8f70b4
                *--p = '0';
Packit 8f70b4
                p -= decimal_pointlen;
Packit 8f70b4
                memcpy (p, decimal_point, decimal_pointlen);
Packit 8f70b4
              }
Packit 8f70b4
            amt = 1;
Packit 8f70b4
          }
Packit 8f70b4
      }
Packit 8f70b4
Packit 8f70b4
    integerlim = p;
Packit 8f70b4
Packit 8f70b4
    do
Packit 8f70b4
      {
Packit 8f70b4
        int digit = amt % 10;
Packit 8f70b4
        *--p = digit + '0';
Packit 8f70b4
      }
Packit 8f70b4
    while ((amt /= 10) != 0);
Packit 8f70b4
  }
Packit 8f70b4
Packit 8f70b4
 do_grouping:
Packit 8f70b4
  if (opts & human_group_digits)
Packit 8f70b4
    p = group_number (p, integerlim - p, grouping, thousands_sep);
Packit 8f70b4
Packit 8f70b4
  if (opts & human_SI)
Packit 8f70b4
    {
Packit 8f70b4
      if (exponent < 0)
Packit 8f70b4
        {
Packit 8f70b4
          uintmax_t power;
Packit 8f70b4
          exponent = 0;
Packit 8f70b4
          for (power = 1; power < to_block_size; power *= base)
Packit 8f70b4
            if (++exponent == exponent_max)
Packit 8f70b4
              break;
Packit 8f70b4
        }
Packit 8f70b4
Packit 8f70b4
      if ((exponent | (opts & human_B)) && (opts & human_space_before_unit))
Packit 8f70b4
        *psuffix++ = ' ';
Packit 8f70b4
Packit 8f70b4
      if (exponent)
Packit 8f70b4
        *psuffix++ = (! (opts & human_base_1024) && exponent == 1
Packit 8f70b4
                      ? 'k'
Packit 8f70b4
                      : power_letter[exponent]);
Packit 8f70b4
Packit 8f70b4
      if (opts & human_B)
Packit 8f70b4
        {
Packit 8f70b4
          if ((opts & human_base_1024) && exponent)
Packit 8f70b4
            *psuffix++ = 'i';
Packit 8f70b4
          *psuffix++ = 'B';
Packit 8f70b4
        }
Packit 8f70b4
    }
Packit 8f70b4
Packit 8f70b4
  *psuffix = '\0';
Packit 8f70b4
Packit 8f70b4
  return p;
Packit 8f70b4
}
Packit 8f70b4
Packit 8f70b4
Packit 8f70b4
/* The default block size used for output.  This number may change in
Packit 8f70b4
   the future as disks get larger.  */
Packit 8f70b4
#ifndef DEFAULT_BLOCK_SIZE
Packit 8f70b4
# define DEFAULT_BLOCK_SIZE 1024
Packit 8f70b4
#endif
Packit 8f70b4
Packit 8f70b4
static char const *const block_size_args[] = { "human-readable", "si", 0 };
Packit 8f70b4
static int const block_size_opts[] =
Packit 8f70b4
  {
Packit 8f70b4
    human_autoscale + human_SI + human_base_1024,
Packit 8f70b4
    human_autoscale + human_SI
Packit 8f70b4
  };
Packit 8f70b4
Packit 8f70b4
static uintmax_t
Packit 8f70b4
default_block_size (void)
Packit 8f70b4
{
Packit 8f70b4
  return getenv ("POSIXLY_CORRECT") ? 512 : DEFAULT_BLOCK_SIZE;
Packit 8f70b4
}
Packit 8f70b4
Packit 8f70b4
static strtol_error
Packit 8f70b4
humblock (char const *spec, uintmax_t *block_size, int *options)
Packit 8f70b4
{
Packit 8f70b4
  int i;
Packit 8f70b4
  int opts = 0;
Packit 8f70b4
Packit 8f70b4
  if (! spec
Packit 8f70b4
      && ! (spec = getenv ("BLOCK_SIZE"))
Packit 8f70b4
      && ! (spec = getenv ("BLOCKSIZE")))
Packit 8f70b4
    *block_size = default_block_size ();
Packit 8f70b4
  else
Packit 8f70b4
    {
Packit 8f70b4
      if (*spec == '\'')
Packit 8f70b4
        {
Packit 8f70b4
          opts |= human_group_digits;
Packit 8f70b4
          spec++;
Packit 8f70b4
        }
Packit 8f70b4
Packit 8f70b4
      if (0 <= (i = ARGMATCH (spec, block_size_args, block_size_opts)))
Packit 8f70b4
        {
Packit 8f70b4
          opts |= block_size_opts[i];
Packit 8f70b4
          *block_size = 1;
Packit 8f70b4
        }
Packit 8f70b4
      else
Packit 8f70b4
        {
Packit 8f70b4
          char *ptr;
Packit 8f70b4
          strtol_error e = xstrtoumax (spec, &ptr, 0, block_size,
Packit 8f70b4
                                       "eEgGkKmMpPtTyYzZ0");
Packit 8f70b4
          if (e != LONGINT_OK)
Packit 8f70b4
            {
Packit 8f70b4
              *options = 0;
Packit 8f70b4
              return e;
Packit 8f70b4
            }
Packit 8f70b4
          for (; ! ('0' <= *spec && *spec <= '9'); spec++)
Packit 8f70b4
            if (spec == ptr)
Packit 8f70b4
              {
Packit 8f70b4
                opts |= human_SI;
Packit 8f70b4
                if (ptr[-1] == 'B')
Packit 8f70b4
                  opts |= human_B;
Packit 8f70b4
                if (ptr[-1] != 'B' || ptr[-2] == 'i')
Packit 8f70b4
                  opts |= human_base_1024;
Packit 8f70b4
                break;
Packit 8f70b4
              }
Packit 8f70b4
        }
Packit 8f70b4
    }
Packit 8f70b4
Packit 8f70b4
  *options = opts;
Packit 8f70b4
  return LONGINT_OK;
Packit 8f70b4
}
Packit 8f70b4
Packit 8f70b4
enum strtol_error
Packit 8f70b4
human_options (char const *spec, int *opts, uintmax_t *block_size)
Packit 8f70b4
{
Packit 8f70b4
  strtol_error e = humblock (spec, block_size, opts);
Packit 8f70b4
  if (*block_size == 0)
Packit 8f70b4
    {
Packit 8f70b4
      *block_size = default_block_size ();
Packit 8f70b4
      e = LONGINT_INVALID;
Packit 8f70b4
    }
Packit 8f70b4
  return e;
Packit 8f70b4
}