aboutsummaryrefslogtreecommitdiff
path: root/libbb
diff options
context:
space:
mode:
Diffstat (limited to 'libbb')
-rw-r--r--libbb/xfuncs.c60
1 files changed, 54 insertions, 6 deletions
diff --git a/libbb/xfuncs.c b/libbb/xfuncs.c
index c72265003..352515af4 100644
--- a/libbb/xfuncs.c
+++ b/libbb/xfuncs.c
@@ -201,23 +201,71 @@ void xsetenv(const char *key, const char *value)
bb_error_msg_and_die(bb_msg_memory_exhausted);
}
+
+// Converts unsigned long long value into compact 4-char
+// representation. Examples: "1234", "1.2k", " 27M", "123T"
+// Fifth char is always '\0'
+void smart_ulltoa5(unsigned long long ul, char buf[5])
+{
+ char *fmt;
+ char c;
+ unsigned v,idx = 0;
+ ul *= 10;
+ if (ul > 9999*10) { // do not scale if 9999 or less
+ while (ul >= 10000) {
+ ul /= 1024;
+ idx++;
+ }
+ }
+ v = ul; // ullong divisions are expensive, avoid them
+
+ fmt = " 123456789";
+ if (!idx) { // 9999 or less: use 1234 format
+ c = buf[0] = " 123456789"[v/10000];
+ if (c!=' ') fmt = "0123456789";
+ c = buf[1] = fmt[v/1000%10];
+ if (c!=' ') fmt = "0123456789";
+ buf[2] = fmt[v/100%10];
+ buf[3] = "0123456789"[v/10%10];
+ } else {
+ if (v>=10*10) { // scaled value is >=10: use 123M format
+ c = buf[0] = " 123456789"[v/1000];
+ if (c!=' ') fmt = "0123456789";
+ buf[1] = fmt[v/100%10];
+ buf[2] = "0123456789"[v/10%10];
+ } else { // scaled value is <10: use 1.2M format
+ buf[0] = "0123456789"[v/10];
+ buf[1] = '.';
+ buf[2] = "0123456789"[v%10];
+ }
+ // see http://en.wikipedia.org/wiki/Tera
+ buf[3] = " kMGTPEZY"[idx];
+ }
+ buf[4] = '\0';
+}
+
+
// Convert unsigned integer to ascii, writing into supplied buffer. A
// truncated result is always null terminated (unless buflen is 0), and
// contains the first few digits of the result ala strncpy.
+void BUG_sizeof_unsigned_not_4(void);
void utoa_to_buf(unsigned n, char *buf, unsigned buflen)
{
- int i, out = 0;
+ unsigned i, out, res;
+ if (sizeof(unsigned) != 4)
+ BUG_sizeof_unsigned_not_4();
if (buflen) {
- for (i=1000000000; i; i/=10) {
- int res = n/i;
-
- if ((res || out || i == 1) && --buflen>0) {
+ out = 0;
+ for (i = 1000000000; i; i /= 10) {
+ res = n / i;
+ if (res || out || i == 1) {
+ if (!--buflen) break;
out++;
n -= res*i;
*buf++ = '0' + res;
}
}
- *buf = 0;
+ *buf = '\0';
}
}