1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
258db1d6eSArnaldo Carvalho de Melo #include "units.h"
358db1d6eSArnaldo Carvalho de Melo #include <inttypes.h>
43caeafceSArnaldo Carvalho de Melo #include <limits.h>
53caeafceSArnaldo Carvalho de Melo #include <stdlib.h>
63caeafceSArnaldo Carvalho de Melo #include <string.h>
758db1d6eSArnaldo Carvalho de Melo #include <linux/kernel.h>
858db1d6eSArnaldo Carvalho de Melo #include <linux/time64.h>
958db1d6eSArnaldo Carvalho de Melo
parse_tag_value(const char * str,struct parse_tag * tags)103caeafceSArnaldo Carvalho de Melo unsigned long parse_tag_value(const char *str, struct parse_tag *tags)
113caeafceSArnaldo Carvalho de Melo {
123caeafceSArnaldo Carvalho de Melo struct parse_tag *i = tags;
133caeafceSArnaldo Carvalho de Melo
143caeafceSArnaldo Carvalho de Melo while (i->tag) {
153caeafceSArnaldo Carvalho de Melo char *s = strchr(str, i->tag);
163caeafceSArnaldo Carvalho de Melo
173caeafceSArnaldo Carvalho de Melo if (s) {
183caeafceSArnaldo Carvalho de Melo unsigned long int value;
193caeafceSArnaldo Carvalho de Melo char *endptr;
203caeafceSArnaldo Carvalho de Melo
213caeafceSArnaldo Carvalho de Melo value = strtoul(str, &endptr, 10);
223caeafceSArnaldo Carvalho de Melo if (s != endptr)
233caeafceSArnaldo Carvalho de Melo break;
243caeafceSArnaldo Carvalho de Melo
253caeafceSArnaldo Carvalho de Melo if (value > ULONG_MAX / i->mult)
263caeafceSArnaldo Carvalho de Melo break;
273caeafceSArnaldo Carvalho de Melo value *= i->mult;
283caeafceSArnaldo Carvalho de Melo return value;
293caeafceSArnaldo Carvalho de Melo }
303caeafceSArnaldo Carvalho de Melo i++;
313caeafceSArnaldo Carvalho de Melo }
323caeafceSArnaldo Carvalho de Melo
333caeafceSArnaldo Carvalho de Melo return (unsigned long) -1;
343caeafceSArnaldo Carvalho de Melo }
353caeafceSArnaldo Carvalho de Melo
convert_unit_double(double value,char * unit)36*6859bc0eSChangbin Du double convert_unit_double(double value, char *unit)
3758db1d6eSArnaldo Carvalho de Melo {
3858db1d6eSArnaldo Carvalho de Melo *unit = ' ';
3958db1d6eSArnaldo Carvalho de Melo
40*6859bc0eSChangbin Du if (value > 1000.0) {
41*6859bc0eSChangbin Du value /= 1000.0;
4258db1d6eSArnaldo Carvalho de Melo *unit = 'K';
4358db1d6eSArnaldo Carvalho de Melo }
4458db1d6eSArnaldo Carvalho de Melo
45*6859bc0eSChangbin Du if (value > 1000.0) {
46*6859bc0eSChangbin Du value /= 1000.0;
4758db1d6eSArnaldo Carvalho de Melo *unit = 'M';
4858db1d6eSArnaldo Carvalho de Melo }
4958db1d6eSArnaldo Carvalho de Melo
50*6859bc0eSChangbin Du if (value > 1000.0) {
51*6859bc0eSChangbin Du value /= 1000.0;
5258db1d6eSArnaldo Carvalho de Melo *unit = 'G';
5358db1d6eSArnaldo Carvalho de Melo }
5458db1d6eSArnaldo Carvalho de Melo
5558db1d6eSArnaldo Carvalho de Melo return value;
5658db1d6eSArnaldo Carvalho de Melo }
5758db1d6eSArnaldo Carvalho de Melo
convert_unit(unsigned long value,char * unit)58*6859bc0eSChangbin Du unsigned long convert_unit(unsigned long value, char *unit)
59*6859bc0eSChangbin Du {
60*6859bc0eSChangbin Du double v = convert_unit_double((double)value, unit);
61*6859bc0eSChangbin Du
62*6859bc0eSChangbin Du return (unsigned long)v;
63*6859bc0eSChangbin Du }
64*6859bc0eSChangbin Du
unit_number__scnprintf(char * buf,size_t size,u64 n)6558db1d6eSArnaldo Carvalho de Melo int unit_number__scnprintf(char *buf, size_t size, u64 n)
6658db1d6eSArnaldo Carvalho de Melo {
6758db1d6eSArnaldo Carvalho de Melo char unit[4] = "BKMG";
6858db1d6eSArnaldo Carvalho de Melo int i = 0;
6958db1d6eSArnaldo Carvalho de Melo
7058db1d6eSArnaldo Carvalho de Melo while (((n / 1024) > 1) && (i < 3)) {
7158db1d6eSArnaldo Carvalho de Melo n /= 1024;
7258db1d6eSArnaldo Carvalho de Melo i++;
7358db1d6eSArnaldo Carvalho de Melo }
7458db1d6eSArnaldo Carvalho de Melo
7558db1d6eSArnaldo Carvalho de Melo return scnprintf(buf, size, "%" PRIu64 "%c", n, unit[i]);
7658db1d6eSArnaldo Carvalho de Melo }
77