0001
0002 #include "units.h"
0003 #include <inttypes.h>
0004 #include <limits.h>
0005 #include <stdlib.h>
0006 #include <string.h>
0007 #include <linux/kernel.h>
0008 #include <linux/time64.h>
0009
0010 unsigned long parse_tag_value(const char *str, struct parse_tag *tags)
0011 {
0012 struct parse_tag *i = tags;
0013
0014 while (i->tag) {
0015 char *s = strchr(str, i->tag);
0016
0017 if (s) {
0018 unsigned long int value;
0019 char *endptr;
0020
0021 value = strtoul(str, &endptr, 10);
0022 if (s != endptr)
0023 break;
0024
0025 if (value > ULONG_MAX / i->mult)
0026 break;
0027 value *= i->mult;
0028 return value;
0029 }
0030 i++;
0031 }
0032
0033 return (unsigned long) -1;
0034 }
0035
0036 double convert_unit_double(double value, char *unit)
0037 {
0038 *unit = ' ';
0039
0040 if (value > 1000.0) {
0041 value /= 1000.0;
0042 *unit = 'K';
0043 }
0044
0045 if (value > 1000.0) {
0046 value /= 1000.0;
0047 *unit = 'M';
0048 }
0049
0050 if (value > 1000.0) {
0051 value /= 1000.0;
0052 *unit = 'G';
0053 }
0054
0055 return value;
0056 }
0057
0058 unsigned long convert_unit(unsigned long value, char *unit)
0059 {
0060 double v = convert_unit_double((double)value, unit);
0061
0062 return (unsigned long)v;
0063 }
0064
0065 int unit_number__scnprintf(char *buf, size_t size, u64 n)
0066 {
0067 char unit[4] = "BKMG";
0068 int i = 0;
0069
0070 while (((n / 1024) > 1) && (i < 3)) {
0071 n /= 1024;
0072 i++;
0073 }
0074
0075 return scnprintf(buf, size, "%" PRIu64 "%c", n, unit[i]);
0076 }