1 #include "string.h" 2 #include "util.h" 3 4 static int hex(char ch) 5 { 6 if ((ch >= '0') && (ch <= '9')) 7 return ch - '0'; 8 if ((ch >= 'a') && (ch <= 'f')) 9 return ch - 'a' + 10; 10 if ((ch >= 'A') && (ch <= 'F')) 11 return ch - 'A' + 10; 12 return -1; 13 } 14 15 /* 16 * While we find nice hex chars, build a long_val. 17 * Return number of chars processed. 18 */ 19 int hex2u64(const char *ptr, u64 *long_val) 20 { 21 const char *p = ptr; 22 *long_val = 0; 23 24 while (*p) { 25 const int hex_val = hex(*p); 26 27 if (hex_val < 0) 28 break; 29 30 *long_val = (*long_val << 4) | hex_val; 31 p++; 32 } 33 34 return p - ptr; 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 } 229 230 /* Glob expression pattern matching */ 231 bool strglobmatch(const char *str, const char *pat) 232 { 233 while (*str && *pat && *pat != '*') { 234 if (*pat == '?') { 235 str++; 236 pat++; 237 } else 238 if (*str++ != *pat++) 239 return false; 240 } 241 /* Check wild card */ 242 if (*pat == '*') { 243 while (*pat == '*') 244 pat++; 245 if (!*pat) /* Tail wild card matches all */ 246 return true; 247 while (*str) 248 if (strglobmatch(str++, pat)) 249 return true; 250 } 251 return !*str && !*pat; 252 } 253 254