* Look for an entry in map that match string[0:len]; string[len] * does not have to be NUL (but it could be). */
| 248 | * does not have to be NUL (but it could be). |
| 249 | */ |
| 250 | static struct string_list_item *lookup_prefix(struct string_list *map, |
| 251 | const char *string, size_t len) |
| 252 | { |
| 253 | bool exact_match; |
| 254 | size_t i = string_list_find_insert_index(map, string, &exact_match); |
| 255 | if (exact_match) { |
| 256 | if (!string[len]) |
| 257 | return &map->items[i]; |
| 258 | /* |
| 259 | * that map entry matches exactly to the string, including |
| 260 | * the cruft at the end beyond "len". That is not a match |
| 261 | * with string[0:len] that we are looking for. |
| 262 | */ |
| 263 | } else if (!string[len]) { |
| 264 | /* |
| 265 | * asked with the whole string, and got nothing. No |
| 266 | * matching entry can exist in the map. |
| 267 | */ |
| 268 | return NULL; |
| 269 | } |
| 270 | |
| 271 | /* |
| 272 | * i is at the exact match to an overlong key, or location the |
| 273 | * overlong key would be inserted, which must come after the |
| 274 | * real location of the key if one exists. |
| 275 | */ |
| 276 | while (i-- && i < map->nr) { |
| 277 | int cmp = strncasecmp(map->items[i].string, string, len); |
| 278 | if (cmp < 0) |
| 279 | /* |
| 280 | * "i" points at a key definitely below the prefix; |
| 281 | * the map does not have string[0:len] in it. |
| 282 | */ |
| 283 | break; |
| 284 | else if (!cmp && !map->items[i].string[len]) |
| 285 | /* found it */ |
| 286 | return &map->items[i]; |
| 287 | /* |
| 288 | * otherwise, the string at "i" may be string[0:len] |
| 289 | * followed by a string that sorts later than string[len:]; |
| 290 | * keep trying. |
| 291 | */ |
| 292 | } |
| 293 | return NULL; |
| 294 | } |
| 295 | |
| 296 | int map_user(struct string_list *map, |
| 297 | const char **email, size_t *emaillen, |
no test coverage detected