summaryrefslogtreecommitdiff
path: root/i/pc104/initrd/conf/busybox/libbb/human_readable.c
diff options
context:
space:
mode:
authorjutteau2007-05-11 18:10:19 +0000
committerjutteau2007-05-11 18:10:19 +0000
commit5e1a84ab74d5e97582427f016f291a8c11e66f99 (patch)
treeddae3f36a21e7fa7c97145f4a49edcfe50063aa3 /i/pc104/initrd/conf/busybox/libbb/human_readable.c
parentb95709754c870cbb793266ce8e605a81d01a4f75 (diff)
Completion du script de mise à jour de la pc-104 :
* Ajout des sources de busybox dans ./conf/busybox/ * Ajout d'un fichier réclamé par les script dans ./conf/busybox.links
Diffstat (limited to 'i/pc104/initrd/conf/busybox/libbb/human_readable.c')
-rw-r--r--i/pc104/initrd/conf/busybox/libbb/human_readable.c89
1 files changed, 89 insertions, 0 deletions
diff --git a/i/pc104/initrd/conf/busybox/libbb/human_readable.c b/i/pc104/initrd/conf/busybox/libbb/human_readable.c
new file mode 100644
index 0000000..ff1b551
--- /dev/null
+++ b/i/pc104/initrd/conf/busybox/libbb/human_readable.c
@@ -0,0 +1,89 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * June 30, 2001 Manuel Novoa III
+ *
+ * All-integer version (hey, not everyone has floating point) of
+ * make_human_readable_str, modified from similar code I had written
+ * for busybox several months ago.
+ *
+ * Notes:
+ * 1) I'm using an unsigned long long to hold the product size * block_size,
+ * as df (which calls this routine) could request a representation of a
+ * partition size in bytes > max of unsigned long. If long longs aren't
+ * available, it would be possible to do what's needed using polynomial
+ * representations (say, powers of 1024) and manipulating coefficients.
+ * The base ten "bytes" output could be handled similarly.
+ *
+ * 2) This routine always outputs a decimal point and a tenths digit when
+ * display_unit != 0. Hence, it isn't uncommon for the returned string
+ * to have a length of 5 or 6.
+ *
+ * It might be nice to add a flag to indicate no decimal digits in
+ * that case. This could be either an additional parameter, or a
+ * special value of display_unit. Such a flag would also be nice for du.
+ *
+ * Some code to omit the decimal point and tenths digit is sketched out
+ * and "#if 0"'d below.
+ */
+
+#include <stdio.h>
+#include "libbb.h"
+
+const char *make_human_readable_str(unsigned long long size,
+ unsigned long block_size, unsigned long display_unit)
+{
+ /* The code will adjust for additional (appended) units. */
+ static const char zero_and_units[] = { '0', 0, 'k', 'M', 'G', 'T' };
+ static const char fmt[] = "%llu";
+ static const char fmt_tenths[] = "%llu.%d%c";
+
+ static char str[21]; /* Sufficient for 64 bit unsigned integers. */
+
+ unsigned long long val;
+ int frac;
+ const char *u;
+ const char *f;
+
+ u = zero_and_units;
+ f = fmt;
+ frac = 0;
+
+ val = size * block_size;
+ if (val == 0) {
+ return u;
+ }
+
+ if (display_unit) {
+ val += display_unit/2; /* Deal with rounding. */
+ val /= display_unit; /* Don't combine with the line above!!! */
+ } else {
+ ++u;
+ while ((val >= 1024)
+ && (u < zero_and_units + sizeof(zero_and_units) - 1)
+ ) {
+ f = fmt_tenths;
+ ++u;
+ frac = (((int)(val % 1024)) * 10 + 1024/2) / 1024;
+ val /= 1024;
+ }
+ if (frac >= 10) { /* We need to round up here. */
+ ++val;
+ frac = 0;
+ }
+#if 0
+ /* Sample code to omit decimal point and tenths digit. */
+ if ( /* no_tenths */ 1 ) {
+ if ( frac >= 5 ) {
+ ++val;
+ }
+ f = "%llu%*c" /* fmt_no_tenths */ ;
+ frac = 1;
+ }
+#endif
+ }
+
+ /* If f==fmt then 'frac' and 'u' are ignored. */
+ snprintf(str, sizeof(str), f, val, frac, *u);
+
+ return str;
+}