blob: 0977cf4317894c4ee02f1e402d66aab705caaf8f [file] [log] [blame]
Arnaldo Carvalho de Meloa2a99e82009-10-05 14:26:18 -03001#include <string.h>
Hitoshi Mitaked2fb8b42009-11-15 20:36:53 +09002#include <stdlib.h>
Arnaldo Carvalho de Meloea5cc872009-06-01 22:31:03 -03003#include "string.h"
Hitoshi Mitaked2fb8b42009-11-15 20:36:53 +09004#include "util.h"
Arnaldo Carvalho de Meloea5cc872009-06-01 22:31:03 -03005
6static 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 */
Paul Mackerras9cffa8d2009-06-19 22:21:42 +100021int hex2u64(const char *ptr, u64 *long_val)
Arnaldo Carvalho de Meloea5cc872009-06-01 22:31:03 -030022{
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}
Arnaldo Carvalho de Meloa2a99e82009-10-05 14:26:18 -030038
39char *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}
Hitoshi Mitaked2fb8b42009-11-15 20:36:53 +090048
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 */
55s64 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;
76kilo:
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;
87mega:
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;
98giga:
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;
109tera:
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
125out_err:
126 length = -1;
127out:
128 return length;
129}
Masami Hiramatsue1c01d62009-11-30 19:20:05 -0500130
131/*
132 * Helper function for splitting a string into an argv-like array.
133 * originaly copied from lib/argv_split.c
134 */
135static const char *skip_sep(const char *cp)
136{
137 while (*cp && isspace(*cp))
138 cp++;
139
140 return cp;
141}
142
143static const char *skip_arg(const char *cp)
144{
145 while (*cp && !isspace(*cp))
146 cp++;
147
148 return cp;
149}
150
151static int count_argc(const char *str)
152{
153 int count = 0;
154
155 while (*str) {
156 str = skip_sep(str);
157 if (*str) {
158 count++;
159 str = skip_arg(str);
160 }
161 }
162
163 return count;
164}
165
166/**
167 * argv_free - free an argv
168 * @argv - the argument vector to be freed
169 *
170 * Frees an argv and the strings it points to.
171 */
172void argv_free(char **argv)
173{
174 char **p;
175 for (p = argv; *p; p++)
176 free(*p);
177
178 free(argv);
179}
180
181/**
182 * argv_split - split a string at whitespace, returning an argv
183 * @str: the string to be split
184 * @argcp: returned argument count
185 *
186 * Returns an array of pointers to strings which are split out from
187 * @str. This is performed by strictly splitting on white-space; no
188 * quote processing is performed. Multiple whitespace characters are
189 * considered to be a single argument separator. The returned array
190 * is always NULL-terminated. Returns NULL on memory allocation
191 * failure.
192 */
193char **argv_split(const char *str, int *argcp)
194{
195 int argc = count_argc(str);
196 char **argv = zalloc(sizeof(*argv) * (argc+1));
197 char **argvp;
198
199 if (argv == NULL)
200 goto out;
201
202 if (argcp)
203 *argcp = argc;
204
205 argvp = argv;
206
207 while (*str) {
208 str = skip_sep(str);
209
210 if (*str) {
211 const char *p = str;
212 char *t;
213
214 str = skip_arg(str);
215
216 t = strndup(p, str-p);
217 if (t == NULL)
218 goto fail;
219 *argvp++ = t;
220 }
221 }
222 *argvp = NULL;
223
224out:
225 return argv;
226
227fail:
228 argv_free(argv);
229 return NULL;
230}