diff options
| author | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-12-06 12:00:33 -0500 |
|---|---|---|
| committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-12-06 12:00:33 -0500 |
| commit | 3d14b5beba35250c548d3851a2b84fce742d8311 (patch) | |
| tree | 065e3d93c3fcbc5ee4c44fa78662393cddbdf6de /tools/perf/util/string.c | |
| parent | 0719dc341389882cc834ed18fc9b7fc6006b2b85 (diff) | |
| parent | 1bf8e6219552d5dd27012d567ec8c4bb9c2d86b4 (diff) | |
Merge branch 'sa1100' into devel
Diffstat (limited to 'tools/perf/util/string.c')
| -rw-r--r-- | tools/perf/util/string.c | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/tools/perf/util/string.c b/tools/perf/util/string.c index c93eca9a7be3..f24a8cc933d5 100644 --- a/tools/perf/util/string.c +++ b/tools/perf/util/string.c | |||
| @@ -1,4 +1,5 @@ | |||
| 1 | #include "string.h" | 1 | #include "string.h" |
| 2 | #include "util.h" | ||
| 2 | 3 | ||
| 3 | static int hex(char ch) | 4 | static int hex(char ch) |
| 4 | { | 5 | { |
| @@ -32,3 +33,196 @@ int hex2u64(const char *ptr, u64 *long_val) | |||
| 32 | 33 | ||
| 33 | return p - ptr; | 34 | return p - ptr; |
| 34 | } | 35 | } |
| 36 | |||
| 37 | char *strxfrchar(char *s, char from, char to) | ||
| 38 | { | ||
| 39 | char *p = s; | ||
| 40 | |||
| 41 | while ((p = strchr(p, from)) != NULL) | ||
| 42 | *p++ = to; | ||
| 43 | |||
| 44 | return s; | ||
| 45 | } | ||
| 46 | |||
| 47 | #define K 1024LL | ||
| 48 | /* | ||
| 49 | * perf_atoll() | ||
| 50 | * Parse (\d+)(b|B|kb|KB|mb|MB|gb|GB|tb|TB) (e.g. "256MB") | ||
| 51 | * and return its numeric value | ||
| 52 | */ | ||
| 53 | s64 perf_atoll(const char *str) | ||
| 54 | { | ||
| 55 | unsigned int i; | ||
| 56 | s64 length = -1, unit = 1; | ||
| 57 | |||
| 58 | if (!isdigit(str[0])) | ||
| 59 | goto out_err; | ||
| 60 | |||
| 61 | for (i = 1; i < strlen(str); i++) { | ||
| 62 | switch (str[i]) { | ||
| 63 | case 'B': | ||
| 64 | case 'b': | ||
| 65 | break; | ||
| 66 | case 'K': | ||
| 67 | if (str[i + 1] != 'B') | ||
| 68 | goto out_err; | ||
| 69 | else | ||
| 70 | goto kilo; | ||
| 71 | case 'k': | ||
| 72 | if (str[i + 1] != 'b') | ||
| 73 | goto out_err; | ||
| 74 | kilo: | ||
| 75 | unit = K; | ||
| 76 | break; | ||
| 77 | case 'M': | ||
| 78 | if (str[i + 1] != 'B') | ||
| 79 | goto out_err; | ||
| 80 | else | ||
| 81 | goto mega; | ||
| 82 | case 'm': | ||
| 83 | if (str[i + 1] != 'b') | ||
| 84 | goto out_err; | ||
| 85 | mega: | ||
| 86 | unit = K * K; | ||
| 87 | break; | ||
| 88 | case 'G': | ||
| 89 | if (str[i + 1] != 'B') | ||
| 90 | goto out_err; | ||
| 91 | else | ||
| 92 | goto giga; | ||
| 93 | case 'g': | ||
| 94 | if (str[i + 1] != 'b') | ||
| 95 | goto out_err; | ||
| 96 | giga: | ||
| 97 | unit = K * K * K; | ||
| 98 | break; | ||
| 99 | case 'T': | ||
| 100 | if (str[i + 1] != 'B') | ||
| 101 | goto out_err; | ||
| 102 | else | ||
| 103 | goto tera; | ||
| 104 | case 't': | ||
| 105 | if (str[i + 1] != 'b') | ||
| 106 | goto out_err; | ||
| 107 | tera: | ||
| 108 | unit = K * K * K * K; | ||
| 109 | break; | ||
| 110 | case '\0': /* only specified figures */ | ||
| 111 | unit = 1; | ||
| 112 | break; | ||
| 113 | default: | ||
| 114 | if (!isdigit(str[i])) | ||
| 115 | goto out_err; | ||
| 116 | break; | ||
| 117 | } | ||
| 118 | } | ||
| 119 | |||
| 120 | length = atoll(str) * unit; | ||
| 121 | goto out; | ||
| 122 | |||
| 123 | out_err: | ||
| 124 | length = -1; | ||
| 125 | out: | ||
| 126 | return length; | ||
| 127 | } | ||
| 128 | |||
| 129 | /* | ||
| 130 | * Helper function for splitting a string into an argv-like array. | ||
| 131 | * originaly copied from lib/argv_split.c | ||
| 132 | */ | ||
| 133 | static const char *skip_sep(const char *cp) | ||
| 134 | { | ||
| 135 | while (*cp && isspace(*cp)) | ||
| 136 | cp++; | ||
| 137 | |||
| 138 | return cp; | ||
| 139 | } | ||
| 140 | |||
| 141 | static const char *skip_arg(const char *cp) | ||
| 142 | { | ||
| 143 | while (*cp && !isspace(*cp)) | ||
| 144 | cp++; | ||
| 145 | |||
| 146 | return cp; | ||
| 147 | } | ||
| 148 | |||
| 149 | static int count_argc(const char *str) | ||
| 150 | { | ||
| 151 | int count = 0; | ||
| 152 | |||
| 153 | while (*str) { | ||
| 154 | str = skip_sep(str); | ||
| 155 | if (*str) { | ||
| 156 | count++; | ||
| 157 | str = skip_arg(str); | ||
| 158 | } | ||
| 159 | } | ||
| 160 | |||
| 161 | return count; | ||
| 162 | } | ||
| 163 | |||
| 164 | /** | ||
| 165 | * argv_free - free an argv | ||
| 166 | * @argv - the argument vector to be freed | ||
| 167 | * | ||
| 168 | * Frees an argv and the strings it points to. | ||
| 169 | */ | ||
| 170 | void argv_free(char **argv) | ||
| 171 | { | ||
| 172 | char **p; | ||
| 173 | for (p = argv; *p; p++) | ||
| 174 | free(*p); | ||
| 175 | |||
| 176 | free(argv); | ||
| 177 | } | ||
| 178 | |||
| 179 | /** | ||
| 180 | * argv_split - split a string at whitespace, returning an argv | ||
| 181 | * @str: the string to be split | ||
| 182 | * @argcp: returned argument count | ||
| 183 | * | ||
| 184 | * Returns an array of pointers to strings which are split out from | ||
| 185 | * @str. This is performed by strictly splitting on white-space; no | ||
| 186 | * quote processing is performed. Multiple whitespace characters are | ||
| 187 | * considered to be a single argument separator. The returned array | ||
| 188 | * is always NULL-terminated. Returns NULL on memory allocation | ||
| 189 | * failure. | ||
| 190 | */ | ||
| 191 | char **argv_split(const char *str, int *argcp) | ||
| 192 | { | ||
| 193 | int argc = count_argc(str); | ||
| 194 | char **argv = zalloc(sizeof(*argv) * (argc+1)); | ||
| 195 | char **argvp; | ||
| 196 | |||
| 197 | if (argv == NULL) | ||
| 198 | goto out; | ||
| 199 | |||
| 200 | if (argcp) | ||
| 201 | *argcp = argc; | ||
| 202 | |||
| 203 | argvp = argv; | ||
| 204 | |||
| 205 | while (*str) { | ||
| 206 | str = skip_sep(str); | ||
| 207 | |||
| 208 | if (*str) { | ||
| 209 | const char *p = str; | ||
| 210 | char *t; | ||
| 211 | |||
| 212 | str = skip_arg(str); | ||
| 213 | |||
| 214 | t = strndup(p, str-p); | ||
| 215 | if (t == NULL) | ||
| 216 | goto fail; | ||
| 217 | *argvp++ = t; | ||
| 218 | } | ||
| 219 | } | ||
| 220 | *argvp = NULL; | ||
| 221 | |||
| 222 | out: | ||
| 223 | return argv; | ||
| 224 | |||
| 225 | fail: | ||
| 226 | argv_free(argv); | ||
| 227 | return NULL; | ||
| 228 | } | ||
