source src/util.c
| Line | Flow | Count | Block(s) | Source |
|---|---|---|---|---|
| 1 | - | /* | ||
| 2 | - | * Copyright (C) the libgit2 contributors. All rights reserved. | ||
| 3 | - | * | ||
| 4 | - | * This file is part of libgit2, distributed under the GNU GPL v2 with | ||
| 5 | - | * a Linking Exception. For full terms see the included COPYING file. | ||
| 6 | - | */ | ||
| 7 | - | |||
| 8 | - | #include "util.h" | ||
| 9 | - | |||
| 10 | - | #include "common.h" | ||
| 11 | - | |||
| 12 | - | #ifdef GIT_WIN32 | ||
| 13 | - | # include "win32/utf-conv.h" | ||
| 14 | - | # include "win32/w32_buffer.h" | ||
| 15 | - | |||
| 16 | - | # ifdef HAVE_QSORT_S | ||
| 17 | - | # include <search.h> | ||
| 18 | - | # endif | ||
| 19 | - | #endif | ||
| 20 | - | |||
| 21 | - | #ifdef _MSC_VER | ||
| 22 | - | # include <Shlwapi.h> | ||
| 23 | - | #endif | ||
| 24 | - | |||
| 25 | ![]() |
- | 2 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files)int git__strntol64(int64_t *result, const char *nptr, size_t nptr_len, const char **endptr, int base) |
| 26 | - | { | ||
| 27 | - | const char *p; | ||
| 28 | - | int64_t n, nn; | ||
| 29 | - | int c, ovfl, v, neg, ndig; | ||
| 30 | - | |||
| 31 | - | 2 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) p = nptr; | |
| 32 | - | 2 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) neg = 0; | |
| 33 | - | 2 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) n = 0; | |
| 34 | - | 2 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) ndig = 0; | |
| 35 | - | 2 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) ovfl = 0; | |
| 36 | - | |||
| 37 | - | /* | ||
| 38 | - | * White space | ||
| 39 | - | */ | ||
| 40 | - | 2,4-6 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) while (nptr_len && git__isspace(*p)) | |
| 41 | - | 3 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) p++, nptr_len--; | |
| 42 | - | |||
| 43 | - | 7 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) if (!nptr_len) | |
| 44 | - | 8 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) goto Return; | |
| 45 | - | |||
| 46 | - | /* | ||
| 47 | - | * Sign | ||
| 48 | - | */ | ||
| 49 | - | 9,10 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) if (*p == '-' || *p == '+') { | |
| 50 | - | 11 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) if (*p == '-') | |
| 51 | - | 12 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) neg = 1; | |
| 52 | - | 13 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) p++; | |
| 53 | - | 13 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) nptr_len--; | |
| 54 | - | } | ||
| 55 | - | |||
| 56 | - | 14 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) if (!nptr_len) | |
| 57 | - | 15 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) goto Return; | |
| 58 | - | |||
| 59 | - | /* | ||
| 60 | - | * Automatically detect the base if none was given to us. | ||
| 61 | - | * Right now, we assume that a number starting with '0x' | ||
| 62 | - | * is hexadecimal and a number starting with '0' is | ||
| 63 | - | * octal. | ||
| 64 | - | */ | ||
| 65 | - | 16 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) if (base == 0) { | |
| 66 | - | 17 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) if (*p != '0') | |
| 67 | - | 18 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) base = 10; | |
| 68 | - | 19-21 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) else if (nptr_len > 2 && (p[1] == 'x' || p[1] == 'X')) | |
| 69 | - | 22 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) base = 16; | |
| 70 | - | else | ||
| 71 | - | 23 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) base = 8; | |
| 72 | - | } | ||
| 73 | - | |||
| 74 | - | 24,25 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) if (base < 0 || 36 < base) | |
| 75 | - | goto Return; | ||
| 76 | - | |||
| 77 | - | /* | ||
| 78 | - | * Skip prefix of '0x'-prefixed hexadecimal numbers. There is no | ||
| 79 | - | * need to do the same for '0'-prefixed octal numbers as a | ||
| 80 | - | * leading '0' does not have any impact. Also, if we skip a | ||
| 81 | - | * leading '0' in such a string, then we may end up with no | ||
| 82 | - | * digits left and produce an error later on which isn't one. | ||
| 83 | - | */ | ||
| 84 | - | 26-30 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) if (base == 16 && nptr_len > 2 && p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) { | |
| 85 | - | 31 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) p += 2; | |
| 86 | - | 31 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) nptr_len -= 2; | |
| 87 | - | } | ||
| 88 | - | |||
| 89 | - | /* | ||
| 90 | - | * Non-empty sequence of digits | ||
| 91 | - | */ | ||
| 92 | - | 32,56,57 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) for (; nptr_len > 0; p++,ndig++,nptr_len--) { | |
| 93 | - | 33 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) c = *p; | |
| 94 | - | 33 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) v = base; | |
| 95 | - | 33,34 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) if ('0'<=c && c<='9') | |
| 96 | - | 35 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) v = c - '0'; | |
| 97 | - | 36,37 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) else if ('a'<=c && c<='z') | |
| 98 | - | 38 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) v = c - 'a' + 10; | |
| 99 | - | 39,40 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) else if ('A'<=c && c<='Z') | |
| 100 | - | 41 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) v = c - 'A' + 10; | |
| 101 | - | 42 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) if (v >= base) | |
| 102 | - | 43 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) break; | |
| 103 | - | 44-46 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) v = neg ? -v : v; | |
| 104 | - | 47,48 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) if (n > INT64_MAX / base || n < INT64_MIN / base) { | |
| 105 | - | 49 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) ovfl = 1; | |
| 106 | - | /* Keep on iterating until the end of this number */ | ||
| 107 | - | 49 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) continue; | |
| 108 | - | } | ||
| 109 | - | 50 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) nn = n * base; | |
| 110 | - | 50-52 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) if ((v > 0 && nn > INT64_MAX - v) || | |
| 111 | - | 53 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) (v < 0 && nn < INT64_MIN - v)) { | |
| 112 | - | 54 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) ovfl = 1; | |
| 113 | - | /* Keep on iterating until the end of this number */ | ||
| 114 | - | 54 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) continue; | |
| 115 | - | } | ||
| 116 | - | 55 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) n = nn + v; | |
| 117 | - | } | ||
| 118 | - | |||
| 119 | - | Return: | ||
| 120 | - | 58 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) if (ndig == 0) { | |
| 121 | - | 59 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) git_error_set(GIT_ERROR_INVALID, "failed to convert string to long: not a number"); | |
| 122 | - | 60 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) return -1; | |
| 123 | - | } | ||
| 124 | - | |||
| 125 | - | 61 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) if (endptr) | |
| 126 | - | 62 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) *endptr = p; | |
| 127 | - | |||
| 128 | - | 63 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) if (ovfl) { | |
| 129 | - | 64 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) git_error_set(GIT_ERROR_INVALID, "failed to convert string to long: overflow error"); | |
| 130 | - | 65 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) return -1; | |
| 131 | - | } | ||
| 132 | - | |||
| 133 | - | 66 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) *result = n; | |
| 134 | - | 66 | suppressed: function cannot be solved git__strntol64 (automatic due to inconsistent arc counts in .gcda files) return 0; | |
| 135 | - | } | ||
| 136 | - | |||
| 137 | 239728 | 2 | int git__strntol32(int32_t *result, const char *nptr, size_t nptr_len, const char **endptr, int base) | |
| 138 | - | { | ||
| 139 | - | const char *tmp_endptr; | ||
| 140 | - | int32_t tmp_int; | ||
| 141 | - | int64_t tmp_long; | ||
| 142 | - | int error; | ||
| 143 | - | |||
| 144 | 239734 | 2,3 | if ((error = git__strntol64(&tmp_long, nptr, nptr_len, &tmp_endptr, base)) < 0) | |
| 145 | 18 | 4 | return error; | |
| 146 | - | |||
| 147 | 239716 | 5 | tmp_int = tmp_long & 0xFFFFFFFF; | |
| 148 | 239716 | 5 | if (tmp_int != tmp_long) { | |
| 149 | 3 | 6 | int len = (int)(tmp_endptr - nptr); | |
| 150 | 3 | 6 | git_error_set(GIT_ERROR_INVALID, "failed to convert: '%.*s' is too large", len, nptr); | |
| 151 | 3 | 7 | return -1; | |
| 152 | - | } | ||
| 153 | - | |||
| 154 | 239713 | 8 | *result = tmp_int; | |
| 155 | 239713 | 8 | if (endptr) | |
| 156 | 239704 | 9 | *endptr = tmp_endptr; | |
| 157 | - | |||
| 158 | 239713 | 10 | return error; | |
| 159 | - | } | ||
| 160 | - | |||
| 161 | ![]() |
1676 | 2 | int git__strcasecmp(const char *a, const char *b) |
| 162 | - | { | ||
| 163 | 4425 | 2,4-6 | while (*a && *b && git__tolower(*a) == git__tolower(*b)) | |
| 164 | 2749 | 3 | ++a, ++b; | |
| 165 | 1676 | 7 | return ((unsigned char)git__tolower(*a) - (unsigned char)git__tolower(*b)); | |
| 166 | - | } | ||
| 167 | - | |||
| 168 | ![]() |
9 | 2 | int git__strcasesort_cmp(const char *a, const char *b) |
| 169 | - | { | ||
| 170 | 9 | 2 | int cmp = 0; | |
| 171 | - | |||
| 172 | 24 | 2,9,10 | while (*a && *b) { | |
| 173 | 19 | 3 | if (*a != *b) { | |
| 174 | 11 | 4 | if (git__tolower(*a) != git__tolower(*b)) | |
| 175 | 4 | 5 | break; | |
| 176 | - | /* use case in sort order even if not in equivalence */ | ||
| 177 | 7 | 6 | if (!cmp) | |
| 178 | 3 | 7 | cmp = (int)(*(const uint8_t *)a) - (int)(*(const uint8_t *)b); | |
| 179 | - | } | ||
| 180 | - | |||
| 181 | 15 | 8 | ++a, ++b; | |
| 182 | - | } | ||
| 183 | - | |||
| 184 | 9 | 11,12 | if (*a || *b) | |
| 185 | 4 | 13 | return (unsigned char)git__tolower(*a) - (unsigned char)git__tolower(*b); | |
| 186 | - | |||
| 187 | 5 | 14 | return cmp; | |
| 188 | - | } | ||
| 189 | - | |||
| 190 | ![]() |
3736 | 2 | int git__strncasecmp(const char *a, const char *b, size_t sz) |
| 191 | - | { | ||
| 192 | - | int al, bl; | ||
| 193 | - | |||
| 194 | - | do { | ||
| 195 | 3736 | 2 | al = (unsigned char)git__tolower(*a); | |
| 196 | 3736 | 2 | bl = (unsigned char)git__tolower(*b); | |
| 197 | 3736 | 2 | ++a, ++b; | |
| 198 | 3736 | 2-4 | } while (--sz && al && al == bl); | |
| 199 | - | |||
| 200 | 2685 | 5 | return al - bl; | |
| 201 | - | } | ||
| 202 | - | |||
| 203 | ![]() |
200 | 2 | void git__strntolower(char *str, size_t len) |
| 204 | - | { | ||
| 205 | - | size_t i; | ||
| 206 | - | |||
| 207 | 997 | 2-4 | for (i = 0; i < len; ++i) { | |
| 208 | 797 | 3 | str[i] = (char)git__tolower(str[i]); | |
| 209 | - | } | ||
| 210 | 200 | 5 | } | |
| 211 | - | |||
| 212 | ##### | 2 | void git__strtolower(char *str) | |
| 213 | - | { | ||
| 214 | ##### | 2 | git__strntolower(str, strlen(str)); | |
| 215 | ##### | 3 | } | |
| 216 | - | |||
| 217 | 167640 | 2 | GIT_INLINE(int) prefixcmp(const char *str, size_t str_n, const char *prefix, bool icase) | |
| 218 | - | { | ||
| 219 | - | int s, p; | ||
| 220 | - | |||
| 221 | 443655 | 2,9 | while (str_n--) { | |
| 222 | 384964 | 3 | s = (unsigned char)*str++; | |
| 223 | 384964 | 3 | p = (unsigned char)*prefix++; | |
| 224 | - | |||
| 225 | 384964 | 3 | if (icase) { | |
| 226 | 1395 | 4 | s = git__tolower(s); | |
| 227 | 1395 | 4 | p = git__tolower(p); | |
| 228 | - | } | ||
| 229 | - | |||
| 230 | 384964 | 5 | if (!p) | |
| 231 | 4365 | 6 | return 0; | |
| 232 | - | |||
| 233 | 380599 | 7 | if (s != p) | |
| 234 | 104584 | 8 | return s - p; | |
| 235 | - | } | ||
| 236 | - | |||
| 237 | 58691 | 10 | return (0 - *prefix); | |
| 238 | - | } | ||
| 239 | - | |||
| 240 | 13843951 | 2 | int git__prefixcmp(const char *str, const char *prefix) | |
| 241 | - | { | ||
| 242 | - | unsigned char s, p; | ||
| 243 | - | |||
| 244 | - | while (1) { | ||
| 245 | 13843951 | 2 | p = *prefix++; | |
| 246 | 13843951 | 2 | s = *str++; | |
| 247 | - | |||
| 248 | 13843951 | 2 | if (!p) | |
| 249 | 418311 | 3 | return 0; | |
| 250 | - | |||
| 251 | 13425640 | 4 | if (s != p) | |
| 252 | 329032 | 5 | return s - p; | |
| 253 | 13096608 | 6 | } | |
| 254 | - | } | ||
| 255 | - | |||
| 256 | 166231 | 2 | int git__prefixncmp(const char *str, size_t str_n, const char *prefix) | |
| 257 | - | { | ||
| 258 | 166231 | 2 | return prefixcmp(str, str_n, prefix, false); | |
| 259 | - | } | ||
| 260 | - | |||
| 261 | 844 | 2 | int git__prefixcmp_icase(const char *str, const char *prefix) | |
| 262 | - | { | ||
| 263 | 844 | 2 | return prefixcmp(str, SIZE_MAX, prefix, true); | |
| 264 | - | } | ||
| 265 | - | |||
| 266 | 20 | 2 | int git__prefixncmp_icase(const char *str, size_t str_n, const char *prefix) | |
| 267 | - | { | ||
| 268 | 20 | 2 | return prefixcmp(str, str_n, prefix, true); | |
| 269 | - | } | ||
| 270 | - | |||
| 271 | 198800 | 2 | int git__suffixcmp(const char *str, const char *suffix) | |
| 272 | - | { | ||
| 273 | 198800 | 2 | size_t a = strlen(str); | |
| 274 | 198800 | 2 | size_t b = strlen(suffix); | |
| 275 | 198800 | 2 | if (a < b) | |
| 276 | 73762 | 3 | return -1; | |
| 277 | 125038 | 4 | return strcmp(str + (a - b), suffix); | |
| 278 | - | } | ||
| 279 | - | |||
| 280 | ![]() |
16 | 2 | char *git__strtok(char **end, const char *sep) |
| 281 | - | { | ||
| 282 | 16 | 2 | char *ptr = *end; | |
| 283 | - | |||
| 284 | 16 | 2,4,5 | while (*ptr && strchr(sep, *ptr)) | |
| 285 | ##### | 3 | ++ptr; | |
| 286 | - | |||
| 287 | 16 | 6 | if (*ptr) { | |
| 288 | 8 | 7 | char *start = ptr; | |
| 289 | 8 | 7 | *end = start + 1; | |
| 290 | - | |||
| 291 | 343 | 7,9,10 | while (**end && !strchr(sep, **end)) | |
| 292 | 335 | 8 | ++*end; | |
| 293 | - | |||
| 294 | 8 | 11 | if (**end) { | |
| 295 | 8 | 12 | **end = '\0'; | |
| 296 | 8 | 12 | ++*end; | |
| 297 | - | } | ||
| 298 | - | |||
| 299 | 8 | 13 | return start; | |
| 300 | - | } | ||
| 301 | - | |||
| 302 | 8 | 14 | return NULL; | |
| 303 | - | } | ||
| 304 | - | |||
| 305 | - | /* Similar to strtok, but does not collapse repeated tokens. */ | ||
| 306 | ![]() |
182 | 2 | char *git__strsep(char **end, const char *sep) |
| 307 | - | { | ||
| 308 | 182 | 2 | char *start = *end, *ptr = *end; | |
| 309 | - | |||
| 310 | 9983 | 2,4,5 | while (*ptr && !strchr(sep, *ptr)) | |
| 311 | 9801 | 3 | ++ptr; | |
| 312 | - | |||
| 313 | 182 | 6 | if (*ptr) { | |
| 314 | 165 | 7 | *end = ptr + 1; | |
| 315 | 165 | 7 | *ptr = '\0'; | |
| 316 | - | |||
| 317 | 165 | 7 | return start; | |
| 318 | - | } | ||
| 319 | - | |||
| 320 | 17 | 8 | return NULL; | |
| 321 | - | } | ||
| 322 | - | |||
| 323 | 206123 | 2 | size_t git__linenlen(const char *buffer, size_t buffer_len) | |
| 324 | - | { | ||
| 325 | 206123 | 2 | char *nl = memchr(buffer, '\n', buffer_len); | |
| 326 | 206123 | 2 | return nl ? (size_t)(nl - buffer) + 1 : buffer_len; | |
| 327 | - | } | ||
| 328 | - | |||
| 329 | - | /* | ||
| 330 | - | * Adapted Not So Naive algorithm from http://www-igm.univ-mlv.fr/~lecroq/string/ | ||
| 331 | - | */ | ||
| 332 | ![]() |
22 | 2 | const void * git__memmem(const void *haystack, size_t haystacklen, |
| 333 | - | const void *needle, size_t needlelen) | ||
| 334 | - | { | ||
| 335 | - | const char *h, *n; | ||
| 336 | - | size_t j, k, l; | ||
| 337 | - | |||
| 338 | 22 | 2-4 | if (needlelen > haystacklen || !haystacklen || !needlelen) | |
| 339 | 8 | 5 | return NULL; | |
| 340 | - | |||
| 341 | 14 | 6 | h = (const char *) haystack, | |
| 342 | 14 | 6 | n = (const char *) needle; | |
| 343 | - | |||
| 344 | 14 | 6 | if (needlelen == 1) | |
| 345 | 5 | 7 | return memchr(haystack, *n, haystacklen); | |
| 346 | - | |||
| 347 | 9 | 8 | if (n[0] == n[1]) { | |
| 348 | 4 | 9 | k = 2; | |
| 349 | 4 | 9 | l = 1; | |
| 350 | - | } else { | ||
| 351 | 5 | 10 | k = 1; | |
| 352 | 5 | 10 | l = 2; | |
| 353 | - | } | ||
| 354 | - | |||
| 355 | 9 | 11 | j = 0; | |
| 356 | 187 | 11,18 | while (j <= haystacklen - needlelen) { | |
| 357 | 184 | 12 | if (n[1] != h[j + 1]) { | |
| 358 | 163 | 13 | j += k; | |
| 359 | - | } else { | ||
| 360 | 21 | 14,15 | if (memcmp(n + 2, h + j + 2, needlelen - 2) == 0 && | |
| 361 | 17 | 15 | n[0] == h[j]) | |
| 362 | 6 | 16 | return h + j; | |
| 363 | 15 | 17 | j += l; | |
| 364 | - | } | ||
| 365 | - | } | ||
| 366 | - | |||
| 367 | 3 | 19 | return NULL; | |
| 368 | - | } | ||
| 369 | - | |||
| 370 | ![]() |
##### | 2 | void git__hexdump(const char *buffer, size_t len) |
| 371 | - | { | ||
| 372 | - | static const size_t LINE_WIDTH = 16; | ||
| 373 | - | |||
| 374 | - | size_t line_count, last_line, i, j; | ||
| 375 | - | const char *line; | ||
| 376 | - | |||
| 377 | ##### | 2 | line_count = (len / LINE_WIDTH); | |
| 378 | ##### | 2 | last_line = (len % LINE_WIDTH); | |
| 379 | - | |||
| 380 | ##### | 2,20,21 | for (i = 0; i < line_count; ++i) { | |
| 381 | ##### | 3 | printf("%08" PRIxZ " ", (i * LINE_WIDTH)); | |
| 382 | - | |||
| 383 | ##### | 4 | line = buffer + (i * LINE_WIDTH); | |
| 384 | ##### | 4,8,9 | for (j = 0; j < LINE_WIDTH; ++j, ++line) { | |
| 385 | ##### | 5 | printf("%02x ", (unsigned char)*line & 0xFF); | |
| 386 | - | |||
| 387 | ##### | 6 | if (j == (LINE_WIDTH / 2)) | |
| 388 | ##### | 7 | printf(" "); | |
| 389 | - | } | ||
| 390 | - | |||
| 391 | ##### | 10 | printf(" |"); | |
| 392 | - | |||
| 393 | ##### | 11 | line = buffer + (i * LINE_WIDTH); | |
| 394 | ##### | 11,17,18 | for (j = 0; j < LINE_WIDTH; ++j, ++line) | |
| 395 | ##### | 12-16 | printf("%c", (*line >= 32 && *line <= 126) ? *line : '.'); | |
| 396 | - | |||
| 397 | ##### | 19 | printf("|\n"); | |
| 398 | - | } | ||
| 399 | - | |||
| 400 | ##### | 22 | if (last_line > 0) { | |
| 401 | ##### | 23 | printf("%08" PRIxZ " ", (line_count * LINE_WIDTH)); | |
| 402 | - | |||
| 403 | ##### | 24 | line = buffer + (line_count * LINE_WIDTH); | |
| 404 | ##### | 24,28,29 | for (j = 0; j < last_line; ++j, ++line) { | |
| 405 | ##### | 25 | printf("%02x ", (unsigned char)*line & 0xFF); | |
| 406 | - | |||
| 407 | ##### | 26 | if (j == (LINE_WIDTH / 2)) | |
| 408 | ##### | 27 | printf(" "); | |
| 409 | - | } | ||
| 410 | - | |||
| 411 | ##### | 30 | if (j < (LINE_WIDTH / 2)) | |
| 412 | ##### | 31 | printf(" "); | |
| 413 | ##### | 32,34,35 | for (j = 0; j < (LINE_WIDTH - last_line); ++j) | |
| 414 | ##### | 33 | printf(" "); | |
| 415 | - | |||
| 416 | ##### | 36 | printf(" |"); | |
| 417 | - | |||
| 418 | ##### | 37 | line = buffer + (line_count * LINE_WIDTH); | |
| 419 | ##### | 37,43,44 | for (j = 0; j < last_line; ++j, ++line) | |
| 420 | ##### | 38-42 | printf("%c", (*line >= 32 && *line <= 126) ? *line : '.'); | |
| 421 | - | |||
| 422 | ##### | 45 | printf("|\n"); | |
| 423 | - | } | ||
| 424 | - | |||
| 425 | ##### | 46 | printf("\n"); | |
| 426 | ##### | 47 | } | |
| 427 | - | |||
| 428 | - | #ifdef GIT_LEGACY_HASH | ||
| 429 | - | uint32_t git__hash(const void *key, int len, unsigned int seed) | ||
| 430 | - | { | ||
| 431 | - | const uint32_t m = 0x5bd1e995; | ||
| 432 | - | const int r = 24; | ||
| 433 | - | uint32_t h = seed ^ len; | ||
| 434 | - | |||
| 435 | - | const unsigned char *data = (const unsigned char *)key; | ||
| 436 | - | |||
| 437 | - | while(len >= 4) { | ||
| 438 | - | uint32_t k = *(uint32_t *)data; | ||
| 439 | - | |||
| 440 | - | k *= m; | ||
| 441 | - | k ^= k >> r; | ||
| 442 | - | k *= m; | ||
| 443 | - | |||
| 444 | - | h *= m; | ||
| 445 | - | h ^= k; | ||
| 446 | - | |||
| 447 | - | data += 4; | ||
| 448 | - | len -= 4; | ||
| 449 | - | } | ||
| 450 | - | |||
| 451 | - | switch(len) { | ||
| 452 | - | case 3: h ^= data[2] << 16; | ||
| 453 | - | case 2: h ^= data[1] << 8; | ||
| 454 | - | case 1: h ^= data[0]; | ||
| 455 | - | h *= m; | ||
| 456 | - | }; | ||
| 457 | - | |||
| 458 | - | h ^= h >> 13; | ||
| 459 | - | h *= m; | ||
| 460 | - | h ^= h >> 15; | ||
| 461 | - | |||
| 462 | - | return h; | ||
| 463 | - | } | ||
| 464 | - | #else | ||
| 465 | - | /* | ||
| 466 | - | Cross-platform version of Murmurhash3 | ||
| 467 | - | http://code.google.com/p/smhasher/wiki/MurmurHash3 | ||
| 468 | - | by Austin Appleby (aappleby@gmail.com) | ||
| 469 | - | |||
| 470 | - | This code is on the public domain. | ||
| 471 | - | */ | ||
| 472 | ![]() |
##### | 2 | uint32_t git__hash(const void *key, int len, uint32_t seed) |
| 473 | - | { | ||
| 474 | - | |||
| 475 | - | #define MURMUR_BLOCK() {\ | ||
| 476 | - | k1 *= c1; \ | ||
| 477 | - | k1 = git__rotl(k1,11);\ | ||
| 478 | - | k1 *= c2;\ | ||
| 479 | - | h1 ^= k1;\ | ||
| 480 | - | h1 = h1*3 + 0x52dce729;\ | ||
| 481 | - | c1 = c1*5 + 0x7b7d159c;\ | ||
| 482 | - | c2 = c2*5 + 0x6bce6396;\ | ||
| 483 | - | } | ||
| 484 | - | |||
| 485 | ##### | 2 | const uint8_t *data = (const uint8_t*)key; | |
| 486 | ##### | 2 | const int nblocks = len / 4; | |
| 487 | - | |||
| 488 | ##### | 2 | const uint32_t *blocks = (const uint32_t *)(data + nblocks * 4); | |
| 489 | ##### | 2 | const uint8_t *tail = (const uint8_t *)(data + nblocks * 4); | |
| 490 | - | |||
| 491 | ##### | 2 | uint32_t h1 = 0x971e137b ^ seed; | |
| 492 | - | uint32_t k1; | ||
| 493 | - | |||
| 494 | ##### | 2 | uint32_t c1 = 0x95543787; | |
| 495 | ##### | 2 | uint32_t c2 = 0x2ad7eb25; | |
| 496 | - | |||
| 497 | - | int i; | ||
| 498 | - | |||
| 499 | ##### | 2-4 | for (i = -nblocks; i; i++) { | |
| 500 | ##### | 3 | k1 = blocks[i]; | |
| 501 | ##### | 3 | MURMUR_BLOCK(); | |
| 502 | - | } | ||
| 503 | - | |||
| 504 | ##### | 5 | k1 = 0; | |
| 505 | - | |||
| 506 | ##### | 5 | switch(len & 3) { | |
| 507 | ##### | 6 | case 3: k1 ^= tail[2] << 16; | |
| 508 | - | /* fall through */ | ||
| 509 | ##### | 7 | case 2: k1 ^= tail[1] << 8; | |
| 510 | - | /* fall through */ | ||
| 511 | ##### | 8 | case 1: k1 ^= tail[0]; | |
| 512 | ##### | 8 | MURMUR_BLOCK(); | |
| 513 | - | } | ||
| 514 | - | |||
| 515 | ##### | 9 | h1 ^= len; | |
| 516 | ##### | 9 | h1 ^= h1 >> 16; | |
| 517 | ##### | 9 | h1 *= 0x85ebca6b; | |
| 518 | ##### | 9 | h1 ^= h1 >> 13; | |
| 519 | ##### | 9 | h1 *= 0xc2b2ae35; | |
| 520 | ##### | 9 | h1 ^= h1 >> 16; | |
| 521 | - | |||
| 522 | ##### | 9 | return h1; | |
| 523 | - | } | ||
| 524 | - | #endif | ||
| 525 | - | |||
| 526 | - | /** | ||
| 527 | - | * A modified `bsearch` from the BSD glibc. | ||
| 528 | - | * | ||
| 529 | - | * Copyright (c) 1990 Regents of the University of California. | ||
| 530 | - | * All rights reserved. | ||
| 531 | - | * Redistribution and use in source and binary forms, with or without | ||
| 532 | - | * modification, are permitted provided that the following conditions | ||
| 533 | - | * are met: | ||
| 534 | - | * 1. Redistributions of source code must retain the above copyright | ||
| 535 | - | * notice, this list of conditions and the following disclaimer. | ||
| 536 | - | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 537 | - | * notice, this list of conditions and the following disclaimer in the | ||
| 538 | - | * documentation and/or other materials provided with the distribution. | ||
| 539 | - | * 3. [rescinded 22 July 1999] | ||
| 540 | - | * 4. Neither the name of the University nor the names of its contributors | ||
| 541 | - | * may be used to endorse or promote products derived from this software | ||
| 542 | - | * without specific prior written permission. | ||
| 543 | - | * | ||
| 544 | - | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
| 545 | - | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 546 | - | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| 547 | - | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
| 548 | - | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 549 | - | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
| 550 | - | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
| 551 | - | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
| 552 | - | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
| 553 | - | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
| 554 | - | * SUCH DAMAGE. | ||
| 555 | - | */ | ||
| 556 | ![]() |
254480 | 2 | int git__bsearch( |
| 557 | - | void **array, | ||
| 558 | - | size_t array_len, | ||
| 559 | - | const void *key, | ||
| 560 | - | int (*compare)(const void *, const void *), | ||
| 561 | - | size_t *position) | ||
| 562 | - | { | ||
| 563 | - | size_t lim; | ||
| 564 | 254480 | 2 | int cmp = -1; | |
| 565 | 254480 | 2 | void **part, **base = array; | |
| 566 | - | |||
| 567 | 844676 | 2,8,9 | for (lim = array_len; lim != 0; lim >>= 1) { | |
| 568 | 609758 | 3 | part = base + (lim >> 1); | |
| 569 | 609758 | 3 | cmp = (*compare)(key, *part); | |
| 570 | 609946 | 4 | if (cmp == 0) { | |
| 571 | 19750 | 5 | base = part; | |
| 572 | 19750 | 5 | break; | |
| 573 | - | } | ||
| 574 | 590196 | 6 | if (cmp > 0) { /* key > p; take right partition */ | |
| 575 | 167997 | 7 | base = part + 1; | |
| 576 | 167997 | 7 | lim--; | |
| 577 | - | } /* else take left partition */ | ||
| 578 | - | } | ||
| 579 | - | |||
| 580 | 254668 | 10 | if (position) | |
| 581 | 248023 | 11 | *position = (base - array); | |
| 582 | - | |||
| 583 | 254668 | 12 | return (cmp == 0) ? 0 : GIT_ENOTFOUND; | |
| 584 | - | } | ||
| 585 | - | |||
| 586 | ![]() |
##### | 2 | int git__bsearch_r( |
| 587 | - | void **array, | ||
| 588 | - | size_t array_len, | ||
| 589 | - | const void *key, | ||
| 590 | - | int (*compare_r)(const void *, const void *, void *), | ||
| 591 | - | void *payload, | ||
| 592 | - | size_t *position) | ||
| 593 | - | { | ||
| 594 | - | size_t lim; | ||
| 595 | ##### | 2 | int cmp = -1; | |
| 596 | ##### | 2 | void **part, **base = array; | |
| 597 | - | |||
| 598 | ##### | 2,8,9 | for (lim = array_len; lim != 0; lim >>= 1) { | |
| 599 | ##### | 3 | part = base + (lim >> 1); | |
| 600 | ##### | 3 | cmp = (*compare_r)(key, *part, payload); | |
| 601 | ##### | 4 | if (cmp == 0) { | |
| 602 | ##### | 5 | base = part; | |
| 603 | ##### | 5 | break; | |
| 604 | - | } | ||
| 605 | ##### | 6 | if (cmp > 0) { /* key > p; take right partition */ | |
| 606 | ##### | 7 | base = part + 1; | |
| 607 | ##### | 7 | lim--; | |
| 608 | - | } /* else take left partition */ | ||
| 609 | - | } | ||
| 610 | - | |||
| 611 | ##### | 10 | if (position) | |
| 612 | ##### | 11 | *position = (base - array); | |
| 613 | - | |||
| 614 | ##### | 12 | return (cmp == 0) ? 0 : GIT_ENOTFOUND; | |
| 615 | - | } | ||
| 616 | - | |||
| 617 | - | /** | ||
| 618 | - | * A strcmp wrapper | ||
| 619 | - | * | ||
| 620 | - | * We don't want direct pointers to the CRT on Windows, we may | ||
| 621 | - | * get stdcall conflicts. | ||
| 622 | - | */ | ||
| 623 | 11267 | 2 | int git__strcmp_cb(const void *a, const void *b) | |
| 624 | - | { | ||
| 625 | 11267 | 2 | return strcmp((const char *)a, (const char *)b); | |
| 626 | - | } | ||
| 627 | - | |||
| 628 | 2 | 2 | int git__strcasecmp_cb(const void *a, const void *b) | |
| 629 | - | { | ||
| 630 | 2 | 2 | return strcasecmp((const char *)a, (const char *)b); | |
| 631 | - | } | ||
| 632 | - | |||
| 633 | ![]() |
15917 | 2 | int git__parse_bool(int *out, const char *value) |
| 634 | - | { | ||
| 635 | - | /* A missing value means true */ | ||
| 636 | 15917 | 2,3 | if (value == NULL || | |
| 637 | 15915 | 3,4 | !strcasecmp(value, "true") || | |
| 638 | 3393 | 4,5 | !strcasecmp(value, "yes") || | |
| 639 | 3392 | 5 | !strcasecmp(value, "on")) { | |
| 640 | 12525 | 6 | *out = 1; | |
| 641 | 12525 | 6 | return 0; | |
| 642 | - | } | ||
| 643 | 3392 | 7,8 | if (!strcasecmp(value, "false") || | |
| 644 | 179 | 8,9 | !strcasecmp(value, "no") || | |
| 645 | 179 | 9,10 | !strcasecmp(value, "off") || | |
| 646 | 179 | 10 | value[0] == '\0') { | |
| 647 | 3214 | 11 | *out = 0; | |
| 648 | 3214 | 11 | return 0; | |
| 649 | - | } | ||
| 650 | - | |||
| 651 | 178 | 12 | return -1; | |
| 652 | - | } | ||
| 653 | - | |||
| 654 | ![]() |
3082 | 2 | size_t git__unescape(char *str) |
| 655 | - | { | ||
| 656 | 3082 | 2 | char *scan, *pos = str; | |
| 657 | - | |||
| 658 | 3082 | 2 | if (!str) | |
| 659 | ##### | 3 | return 0; | |
| 660 | - | |||
| 661 | 44494 | 4,10,11 | for (scan = str; *scan; pos++, scan++) { | |
| 662 | 41412 | 5,6 | if (*scan == '\\' && *(scan + 1) != '\0') | |
| 663 | 6 | 7 | scan++; /* skip '\' but include next char */ | |
| 664 | 41412 | 8 | if (pos != scan) | |
| 665 | 14 | 9 | *pos = *scan; | |
| 666 | - | } | ||
| 667 | - | |||
| 668 | 3082 | 12 | if (pos != scan) { | |
| 669 | 3 | 13 | *pos = '\0'; | |
| 670 | - | } | ||
| 671 | - | |||
| 672 | 3082 | 14 | return (pos - str); | |
| 673 | - | } | ||
| 674 | - | |||
| 675 | - | #if defined(HAVE_QSORT_S) || defined(HAVE_QSORT_R_BSD) | ||
| 676 | - | typedef struct { | ||
| 677 | - | git__sort_r_cmp cmp; | ||
| 678 | - | void *payload; | ||
| 679 | - | } git__qsort_r_glue; | ||
| 680 | - | |||
| 681 | - | static int GIT_STDLIB_CALL git__qsort_r_glue_cmp( | ||
| 682 | - | void *payload, const void *a, const void *b) | ||
| 683 | - | { | ||
| 684 | - | git__qsort_r_glue *glue = payload; | ||
| 685 | - | return glue->cmp(a, b, glue->payload); | ||
| 686 | - | } | ||
| 687 | - | #endif | ||
| 688 | - | |||
| 689 | - | |||
| 690 | - | #if !defined(HAVE_QSORT_R_BSD) && \ | ||
| 691 | - | !defined(HAVE_QSORT_R_GNU) && \ | ||
| 692 | - | !defined(HAVE_QSORT_S) | ||
| 693 | - | static void swap(uint8_t *a, uint8_t *b, size_t elsize) | ||
| 694 | - | { | ||
| 695 | - | char tmp[256]; | ||
| 696 | - | |||
| 697 | - | while (elsize) { | ||
| 698 | - | size_t n = elsize < sizeof(tmp) ? elsize : sizeof(tmp); | ||
| 699 | - | memcpy(tmp, a + elsize - n, n); | ||
| 700 | - | memcpy(a + elsize - n, b + elsize - n, n); | ||
| 701 | - | memcpy(b + elsize - n, tmp, n); | ||
| 702 | - | elsize -= n; | ||
| 703 | - | } | ||
| 704 | - | } | ||
| 705 | - | |||
| 706 | - | static void insertsort( | ||
| 707 | - | void *els, size_t nel, size_t elsize, | ||
| 708 | - | git__sort_r_cmp cmp, void *payload) | ||
| 709 | - | { | ||
| 710 | - | uint8_t *base = els; | ||
| 711 | - | uint8_t *end = base + nel * elsize; | ||
| 712 | - | uint8_t *i, *j; | ||
| 713 | - | |||
| 714 | - | for (i = base + elsize; i < end; i += elsize) | ||
| 715 | - | for (j = i; j > base && cmp(j, j - elsize, payload) < 0; j -= elsize) | ||
| 716 | - | swap(j, j - elsize, elsize); | ||
| 717 | - | } | ||
| 718 | - | #endif | ||
| 719 | - | |||
| 720 | 2984 | 2 | void git__qsort_r( | |
| 721 | - | void *els, size_t nel, size_t elsize, git__sort_r_cmp cmp, void *payload) | ||
| 722 | - | { | ||
| 723 | - | #if defined(HAVE_QSORT_R_BSD) | ||
| 724 | - | git__qsort_r_glue glue = { cmp, payload }; | ||
| 725 | - | qsort_r(els, nel, elsize, &glue, git__qsort_r_glue_cmp); | ||
| 726 | - | #elif defined(HAVE_QSORT_R_GNU) | ||
| 727 | 2984 | 2 | qsort_r(els, nel, elsize, cmp, payload); | |
| 728 | - | #elif defined(HAVE_QSORT_S) | ||
| 729 | - | git__qsort_r_glue glue = { cmp, payload }; | ||
| 730 | - | qsort_s(els, nel, elsize, git__qsort_r_glue_cmp, &glue); | ||
| 731 | - | #else | ||
| 732 | - | insertsort(els, nel, elsize, cmp, payload); | ||
| 733 | - | #endif | ||
| 734 | 2984 | 3 | } | |
| 735 | - | |||
| 736 | - | /* | ||
| 737 | - | * git__utf8_iterate is taken from the utf8proc project, | ||
| 738 | - | * http://www.public-software-group.org/utf8proc | ||
| 739 | - | * | ||
| 740 | - | * Copyright (c) 2009 Public Software Group e. V., Berlin, Germany | ||
| 741 | - | * | ||
| 742 | - | * Permission is hereby granted, free of charge, to any person obtaining a | ||
| 743 | - | * copy of this software and associated documentation files (the ""Software""), | ||
| 744 | - | * to deal in the Software without restriction, including without limitation | ||
| 745 | - | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
| 746 | - | * and/or sell copies of the Software, and to permit persons to whom the | ||
| 747 | - | * Software is furnished to do so, subject to the following conditions: | ||
| 748 | - | * | ||
| 749 | - | * The above copyright notice and this permission notice shall be included in | ||
| 750 | - | * all copies or substantial portions of the Software. | ||
| 751 | - | * | ||
| 752 | - | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 753 | - | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| 754 | - | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| 755 | - | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| 756 | - | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
| 757 | - | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
| 758 | - | * DEALINGS IN THE SOFTWARE. | ||
| 759 | - | */ | ||
| 760 | - | |||
| 761 | - | static const int8_t utf8proc_utf8class[256] = { | ||
| 762 | - | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||
| 763 | - | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||
| 764 | - | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||
| 765 | - | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||
| 766 | - | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||
| 767 | - | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||
| 768 | - | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||
| 769 | - | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | ||
| 770 | - | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 771 | - | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 772 | - | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 773 | - | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 774 | - | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | ||
| 775 | - | 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | ||
| 776 | - | 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, | ||
| 777 | - | 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0 | ||
| 778 | - | }; | ||
| 779 | - | |||
| 780 | ![]() |
21290 | 2 | static int util_utf8_charlen(const uint8_t *str, size_t str_len) |
| 781 | - | { | ||
| 782 | - | size_t length, i; | ||
| 783 | - | |||
| 784 | 21290 | 2 | length = utf8proc_utf8class[str[0]]; | |
| 785 | 21290 | 2 | if (!length) | |
| 786 | 2 | 3 | return -1; | |
| 787 | - | |||
| 788 | 21288 | 4,5 | if (str_len > 0 && length > str_len) | |
| 789 | ##### | 6 | return -1; | |
| 790 | - | |||
| 791 | 21508 | 7,10,11 | for (i = 1; i < length; i++) { | |
| 792 | 224 | 8 | if ((str[i] & 0xC0) != 0x80) | |
| 793 | 4 | 9 | return -1; | |
| 794 | - | } | ||
| 795 | - | |||
| 796 | 21284 | 12 | return (int)length; | |
| 797 | - | } | ||
| 798 | - | |||
| 799 | ![]() |
413 | 2 | int git__utf8_iterate(const uint8_t *str, int str_len, int32_t *dst) |
| 800 | - | { | ||
| 801 | - | int length; | ||
| 802 | 413 | 2 | int32_t uc = -1; | |
| 803 | - | |||
| 804 | 413 | 2 | *dst = -1; | |
| 805 | 413 | 2 | length = util_utf8_charlen(str, str_len); | |
| 806 | 413 | 3 | if (length < 0) | |
| 807 | 5 | 4 | return -1; | |
| 808 | - | |||
| 809 | 408 | 5 | switch (length) { | |
| 810 | - | case 1: | ||
| 811 | 362 | 6 | uc = str[0]; | |
| 812 | 362 | 6 | break; | |
| 813 | - | case 2: | ||
| 814 | ##### | 7 | uc = ((str[0] & 0x1F) << 6) + (str[1] & 0x3F); | |
| 815 | ##### | 7,8 | if (uc < 0x80) uc = -1; | |
| 816 | ##### | 9 | break; | |
| 817 | - | case 3: | ||
| 818 | 46 | 10,10 | uc = ((str[0] & 0x0F) << 12) + ((str[1] & 0x3F) << 6) | |
| 819 | 46 | 10 | + (str[2] & 0x3F); | |
| 820 | 46 | 10-13 | if (uc < 0x800 || (uc >= 0xD800 && uc < 0xE000) || | |
| 821 | 3 | 14,15 | (uc >= 0xFDD0 && uc < 0xFDF0)) uc = -1; | |
| 822 | 46 | 16 | break; | |
| 823 | - | case 4: | ||
| 824 | ##### | 17,17 | uc = ((str[0] & 0x07) << 18) + ((str[1] & 0x3F) << 12) | |
| 825 | ##### | 17 | + ((str[2] & 0x3F) << 6) + (str[3] & 0x3F); | |
| 826 | ##### | 17-19 | if (uc < 0x10000 || uc >= 0x110000) uc = -1; | |
| 827 | ##### | 20 | break; | |
| 828 | - | } | ||
| 829 | - | |||
| 830 | 408 | 21,22 | if (uc < 0 || ((uc & 0xFFFF) >= 0xFFFE)) | |
| 831 | ##### | 23 | return -1; | |
| 832 | - | |||
| 833 | 408 | 24 | *dst = uc; | |
| 834 | 408 | 24 | return length; | |
| 835 | - | } | ||
| 836 | - | |||
| 837 | 945 | 2 | size_t git__utf8_valid_buf_length(const uint8_t *str, size_t str_len) | |
| 838 | - | { | ||
| 839 | 945 | 2 | size_t offset = 0; | |
| 840 | - | |||
| 841 | 21821 | 2,7 | while (offset < str_len) { | |
| 842 | 20877 | 3 | int length = util_utf8_charlen(str + offset, str_len - offset); | |
| 843 | - | |||
| 844 | 20877 | 4 | if (length < 0) | |
| 845 | 1 | 5 | break; | |
| 846 | - | |||
| 847 | 20876 | 6 | offset += length; | |
| 848 | - | } | ||
| 849 | - | |||
| 850 | 945 | 8 | return offset; | |
| 851 | - | } | ||
| 852 | - | |||
| 853 | - | #ifdef GIT_WIN32 | ||
| 854 | - | int git__getenv(git_buf *out, const char *name) | ||
| 855 | - | { | ||
| 856 | - | wchar_t *wide_name = NULL, *wide_value = NULL; | ||
| 857 | - | DWORD value_len; | ||
| 858 | - | int error = -1; | ||
| 859 | - | |||
| 860 | - | git_buf_clear(out); | ||
| 861 | - | |||
| 862 | - | if (git__utf8_to_16_alloc(&wide_name, name) < 0) | ||
| 863 | - | return -1; | ||
| 864 | - | |||
| 865 | - | if ((value_len = GetEnvironmentVariableW(wide_name, NULL, 0)) > 0) { | ||
| 866 | - | wide_value = git__malloc(value_len * sizeof(wchar_t)); | ||
| 867 | - | GIT_ERROR_CHECK_ALLOC(wide_value); | ||
| 868 | - | |||
| 869 | - | value_len = GetEnvironmentVariableW(wide_name, wide_value, value_len); | ||
| 870 | - | } | ||
| 871 | - | |||
| 872 | - | if (value_len) | ||
| 873 | - | error = git_buf_put_w(out, wide_value, value_len); | ||
| 874 | - | else if (GetLastError() == ERROR_ENVVAR_NOT_FOUND) | ||
| 875 | - | error = GIT_ENOTFOUND; | ||
| 876 | - | else | ||
| 877 | - | git_error_set(GIT_ERROR_OS, "could not read environment variable '%s'", name); | ||
| 878 | - | |||
| 879 | - | git__free(wide_name); | ||
| 880 | - | git__free(wide_value); | ||
| 881 | - | return error; | ||
| 882 | - | } | ||
| 883 | - | #else | ||
| 884 | 2045 | 2 | int git__getenv(git_buf *out, const char *name) | |
| 885 | - | { | ||
| 886 | 2045 | 2 | const char *val = getenv(name); | |
| 887 | - | |||
| 888 | 2045 | 3 | git_buf_clear(out); | |
| 889 | - | |||
| 890 | 2045 | 4 | if (!val) | |
| 891 | 1911 | 5 | return GIT_ENOTFOUND; | |
| 892 | - | |||
| 893 | 134 | 6 | return git_buf_puts(out, val); | |
| 894 | - | } | ||
| 895 | - | #endif |