diff options
Diffstat (limited to 'tools/perf/util/string.c')
-rw-r--r-- | tools/perf/util/string.c | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/tools/perf/util/string.c b/tools/perf/util/string.c index 227043577e06..0977cf431789 100644 --- a/tools/perf/util/string.c +++ b/tools/perf/util/string.c | |||
@@ -127,3 +127,104 @@ out_err: | |||
127 | out: | 127 | out: |
128 | return length; | 128 | return length; |
129 | } | 129 | } |
130 | |||
131 | /* | ||
132 | * Helper function for splitting a string into an argv-like array. | ||
133 | * originaly copied from lib/argv_split.c | ||
134 | */ | ||
135 | static const char *skip_sep(const char *cp) | ||
136 | { | ||
137 | while (*cp && isspace(*cp)) | ||
138 | cp++; | ||
139 | |||
140 | return cp; | ||
141 | } | ||
142 | |||
143 | static const char *skip_arg(const char *cp) | ||
144 | { | ||
145 | while (*cp && !isspace(*cp)) | ||
146 | cp++; | ||
147 | |||
148 | return cp; | ||
149 | } | ||
150 | |||
151 | static 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 | */ | ||
172 | void 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 | */ | ||
193 | char **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 | |||
224 | out: | ||
225 | return argv; | ||
226 | |||
227 | fail: | ||
228 | argv_free(argv); | ||
229 | return NULL; | ||
230 | } | ||