Cleanup symbols that should be static
[fio.git] / lib / num2str.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4
5 #include "../fio.h"
6
7 /*
8  * Cheesy number->string conversion, complete with carry rounding error.
9  */
10 char *num2str(unsigned long num, int maxlen, int base, int pow2, int unit_base)
11 {
12         const char *postfix[] = { "", "K", "M", "G", "P", "E" };
13         const char *byte_postfix[] = { "", "B", "bit" };
14         const unsigned int thousand[] = { 1000, 1024 };
15         unsigned int modulo, decimals;
16         int byte_post_index = 0, post_index, carry = 0;
17         char tmp[32];
18         char *buf;
19
20         buf = malloc(128);
21
22         for (post_index = 0; base > 1; post_index++)
23                 base /= thousand[!!pow2];
24
25         switch (unit_base) {
26         case 1:
27                 byte_post_index = 2;
28                 num *= 8;
29                 break;
30         case 8:
31                 byte_post_index = 1;
32                 break;
33         }
34
35         modulo = -1U;
36         while (post_index < sizeof(postfix)) {
37                 sprintf(tmp, "%lu", num);
38                 if (strlen(tmp) <= maxlen)
39                         break;
40
41                 modulo = num % thousand[!!pow2];
42                 num /= thousand[!!pow2];
43                 carry = modulo >= thousand[!!pow2] / 2;
44                 post_index++;
45         }
46
47         if (modulo == -1U) {
48 done:
49                 sprintf(buf, "%lu%s%s", num, postfix[post_index],
50                         byte_postfix[byte_post_index]);
51                 return buf;
52         }
53
54         sprintf(tmp, "%lu", num);
55         decimals = maxlen - strlen(tmp);
56         if (decimals <= 1) {
57                 if (carry)
58                         num++;
59                 goto done;
60         }
61
62         do {
63                 sprintf(tmp, "%u", modulo);
64                 if (strlen(tmp) <= decimals - 1)
65                         break;
66
67                 modulo = (modulo + 9) / 10;
68         } while (1);
69
70         sprintf(buf, "%lu.%u%s%s", num, modulo, postfix[post_index],
71                 byte_postfix[byte_post_index]);
72         return buf;
73 }