1 // SPDX-License-Identifier: GPL-2.0 2 #include "units.h" 3 #include <inttypes.h> 4 #include <limits.h> 5 #include <stdlib.h> 6 #include <string.h> 7 #include <linux/kernel.h> 8 #include <linux/time64.h> 9 10 unsigned long parse_tag_value(const char *str, struct parse_tag *tags) 11 { 12 struct parse_tag *i = tags; 13 14 while (i->tag) { 15 char *s = strchr(str, i->tag); 16 17 if (s) { 18 unsigned long int value; 19 char *endptr; 20 21 value = strtoul(str, &endptr, 10); 22 if (s != endptr) 23 break; 24 25 if (value > ULONG_MAX / i->mult) 26 break; 27 value *= i->mult; 28 return value; 29 } 30 i++; 31 } 32 33 return (unsigned long) -1; 34 } 35 36 double convert_unit_double(double value, char *unit) 37 { 38 *unit = ' '; 39 40 if (value > 1000.0) { 41 value /= 1000.0; 42 *unit = 'K'; 43 } 44 45 if (value > 1000.0) { 46 value /= 1000.0; 47 *unit = 'M'; 48 } 49 50 if (value > 1000.0) { 51 value /= 1000.0; 52 *unit = 'G'; 53 } 54 55 return value; 56 } 57 58 unsigned long convert_unit(unsigned long value, char *unit) 59 { 60 double v = convert_unit_double((double)value, unit); 61 62 return (unsigned long)v; 63 } 64 65 int unit_number__scnprintf(char *buf, size_t size, u64 n) 66 { 67 char unit[4] = "BKMG"; 68 int i = 0; 69 70 while (((n / 1024) > 1) && (i < 3)) { 71 n /= 1024; 72 i++; 73 } 74 75 return scnprintf(buf, size, "%" PRIu64 "%c", n, unit[i]); 76 } 77