162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci#include "units.h" 362306a36Sopenharmony_ci#include <inttypes.h> 462306a36Sopenharmony_ci#include <limits.h> 562306a36Sopenharmony_ci#include <stdlib.h> 662306a36Sopenharmony_ci#include <string.h> 762306a36Sopenharmony_ci#include <linux/kernel.h> 862306a36Sopenharmony_ci#include <linux/time64.h> 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ciunsigned long parse_tag_value(const char *str, struct parse_tag *tags) 1162306a36Sopenharmony_ci{ 1262306a36Sopenharmony_ci struct parse_tag *i = tags; 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci while (i->tag) { 1562306a36Sopenharmony_ci char *s = strchr(str, i->tag); 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci if (s) { 1862306a36Sopenharmony_ci unsigned long int value; 1962306a36Sopenharmony_ci char *endptr; 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci value = strtoul(str, &endptr, 10); 2262306a36Sopenharmony_ci if (s != endptr) 2362306a36Sopenharmony_ci break; 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci if (value > ULONG_MAX / i->mult) 2662306a36Sopenharmony_ci break; 2762306a36Sopenharmony_ci value *= i->mult; 2862306a36Sopenharmony_ci return value; 2962306a36Sopenharmony_ci } 3062306a36Sopenharmony_ci i++; 3162306a36Sopenharmony_ci } 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci return (unsigned long) -1; 3462306a36Sopenharmony_ci} 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_cidouble convert_unit_double(double value, char *unit) 3762306a36Sopenharmony_ci{ 3862306a36Sopenharmony_ci *unit = ' '; 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci if (value > 1000.0) { 4162306a36Sopenharmony_ci value /= 1000.0; 4262306a36Sopenharmony_ci *unit = 'K'; 4362306a36Sopenharmony_ci } 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci if (value > 1000.0) { 4662306a36Sopenharmony_ci value /= 1000.0; 4762306a36Sopenharmony_ci *unit = 'M'; 4862306a36Sopenharmony_ci } 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci if (value > 1000.0) { 5162306a36Sopenharmony_ci value /= 1000.0; 5262306a36Sopenharmony_ci *unit = 'G'; 5362306a36Sopenharmony_ci } 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci return value; 5662306a36Sopenharmony_ci} 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ciunsigned long convert_unit(unsigned long value, char *unit) 5962306a36Sopenharmony_ci{ 6062306a36Sopenharmony_ci double v = convert_unit_double((double)value, unit); 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci return (unsigned long)v; 6362306a36Sopenharmony_ci} 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ciint unit_number__scnprintf(char *buf, size_t size, u64 n) 6662306a36Sopenharmony_ci{ 6762306a36Sopenharmony_ci char unit[4] = "BKMG"; 6862306a36Sopenharmony_ci int i = 0; 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci while (((n / 1024) > 1) && (i < 3)) { 7162306a36Sopenharmony_ci n /= 1024; 7262306a36Sopenharmony_ci i++; 7362306a36Sopenharmony_ci } 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci return scnprintf(buf, size, "%" PRIu64 "%c", n, unit[i]); 7662306a36Sopenharmony_ci} 77