smart_ulltoa5: make available in libbb

This commit is contained in:
Denis Vlasenko 2006-11-05 00:44:39 +00:00
parent 459e4d6cf7
commit aae0311356
3 changed files with 56 additions and 41 deletions

View File

@ -278,6 +278,7 @@ extern FILE *fopen_or_warn(const char *filename, const char *mode);
extern FILE *fopen_or_warn_stdin(const char *filename);
extern void smart_ulltoa5(unsigned long long ul, char buf[5]);
extern void utoa_to_buf(unsigned n, char *buf, unsigned buflen);
extern char *utoa(unsigned n);
extern void itoa_to_buf(int n, char *buf, unsigned buflen);

View File

@ -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';
}
}

View File

@ -214,42 +214,8 @@ static int rdval_diskstats(const char* p, ullong *vec)
static void scale(ullong ul)
{
char *fmt;
char buf[5];
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';
smart_ulltoa5(ul, buf);
put(buf);
}