xref: /linux/tools/perf/util/string.c (revision bcefe12eff5dca6fdfa94ed85e5bee66380d5cd9)
1 #include <string.h>
2 #include <stdlib.h>
3 #include "string.h"
4 #include "util.h"
5 
6 static int hex(char ch)
7 {
8 	if ((ch >= '0') && (ch <= '9'))
9 		return ch - '0';
10 	if ((ch >= 'a') && (ch <= 'f'))
11 		return ch - 'a' + 10;
12 	if ((ch >= 'A') && (ch <= 'F'))
13 		return ch - 'A' + 10;
14 	return -1;
15 }
16 
17 /*
18  * While we find nice hex chars, build a long_val.
19  * Return number of chars processed.
20  */
21 int hex2u64(const char *ptr, u64 *long_val)
22 {
23 	const char *p = ptr;
24 	*long_val = 0;
25 
26 	while (*p) {
27 		const int hex_val = hex(*p);
28 
29 		if (hex_val < 0)
30 			break;
31 
32 		*long_val = (*long_val << 4) | hex_val;
33 		p++;
34 	}
35 
36 	return p - ptr;
37 }
38 
39 char *strxfrchar(char *s, char from, char to)
40 {
41 	char *p = s;
42 
43 	while ((p = strchr(p, from)) != NULL)
44 		*p++ = to;
45 
46 	return s;
47 }
48 
49 #define K 1024LL
50 /*
51  * perf_atoll()
52  * Parse (\d+)(b|B|kb|KB|mb|MB|gb|GB|tb|TB) (e.g. "256MB")
53  * and return its numeric value
54  */
55 s64 perf_atoll(const char *str)
56 {
57 	unsigned int i;
58 	s64 length = -1, unit = 1;
59 
60 	if (!isdigit(str[0]))
61 		goto out_err;
62 
63 	for (i = 1; i < strlen(str); i++) {
64 		switch (str[i]) {
65 		case 'B':
66 		case 'b':
67 			break;
68 		case 'K':
69 			if (str[i + 1] != 'B')
70 				goto out_err;
71 			else
72 				goto kilo;
73 		case 'k':
74 			if (str[i + 1] != 'b')
75 				goto out_err;
76 kilo:
77 			unit = K;
78 			break;
79 		case 'M':
80 			if (str[i + 1] != 'B')
81 				goto out_err;
82 			else
83 				goto mega;
84 		case 'm':
85 			if (str[i + 1] != 'b')
86 				goto out_err;
87 mega:
88 			unit = K * K;
89 			break;
90 		case 'G':
91 			if (str[i + 1] != 'B')
92 				goto out_err;
93 			else
94 				goto giga;
95 		case 'g':
96 			if (str[i + 1] != 'b')
97 				goto out_err;
98 giga:
99 			unit = K * K * K;
100 			break;
101 		case 'T':
102 			if (str[i + 1] != 'B')
103 				goto out_err;
104 			else
105 				goto tera;
106 		case 't':
107 			if (str[i + 1] != 'b')
108 				goto out_err;
109 tera:
110 			unit = K * K * K * K;
111 			break;
112 		case '\0':	/* only specified figures */
113 			unit = 1;
114 			break;
115 		default:
116 			if (!isdigit(str[i]))
117 				goto out_err;
118 			break;
119 		}
120 	}
121 
122 	length = atoll(str) * unit;
123 	goto out;
124 
125 out_err:
126 	length = -1;
127 out:
128 	return length;
129 }
130