diff options
Diffstat (limited to 'mailmap.c')
-rw-r--r-- | mailmap.c | 107 |
1 files changed, 64 insertions, 43 deletions
@@ -5,8 +5,10 @@ #define DEBUG_MAILMAP 0 #if DEBUG_MAILMAP #define debug_mm(...) fprintf(stderr, __VA_ARGS__) +#define debug_str(X) ((X) ? (X) : "(none)") #else static inline void debug_mm(const char *format, ...) {} +static inline const char *debug_str(const char *s) { return s; } #endif const char *git_mailmap_file; @@ -29,7 +31,8 @@ struct mailmap_entry { static void free_mailmap_info(void *p, const char *s) { struct mailmap_info *mi = (struct mailmap_info *)p; - debug_mm("mailmap: -- complex: '%s' -> '%s' <%s>\n", s, mi->name, mi->email); + debug_mm("mailmap: -- complex: '%s' -> '%s' <%s>\n", + s, debug_str(mi->name), debug_str(mi->email)); free(mi->name); free(mi->email); } @@ -37,8 +40,11 @@ static void free_mailmap_info(void *p, const char *s) static void free_mailmap_entry(void *p, const char *s) { struct mailmap_entry *me = (struct mailmap_entry *)p; - debug_mm("mailmap: removing entries for <%s>, with %d sub-entries\n", s, me->namemap.nr); - debug_mm("mailmap: - simple: '%s' <%s>\n", me->name, me->email); + debug_mm("mailmap: removing entries for <%s>, with %d sub-entries\n", + s, me->namemap.nr); + debug_mm("mailmap: - simple: '%s' <%s>\n", + debug_str(me->name), debug_str(me->email)); + free(me->name); free(me->email); @@ -46,19 +52,26 @@ static void free_mailmap_entry(void *p, const char *s) string_list_clear_func(&me->namemap, free_mailmap_info); } +/* + * On some systems (e.g. MinGW 4.0), string.h has _only_ inline + * definition of strcasecmp and no non-inline implementation is + * supplied anywhere, which is, eh, "unusual"; we cannot take an + * address of such a function to store it in namemap.cmp. This is + * here as a workaround---do not assign strcasecmp directly to + * namemap.cmp until we know no systems that matter have such an + * "unusual" string.h. + */ +static int namemap_cmp(const char *a, const char *b) +{ + return strcasecmp(a, b); +} + static void add_mapping(struct string_list *map, - char *new_name, char *new_email, char *old_name, char *old_email) + char *new_name, char *new_email, + char *old_name, char *old_email) { struct mailmap_entry *me; int index; - char *p; - - if (old_email) - for (p = old_email; *p; p++) - *p = tolower(*p); - if (new_email) - for (p = new_email; *p; p++) - *p = tolower(*p); if (old_email == NULL) { old_email = new_email; @@ -68,16 +81,21 @@ static void add_mapping(struct string_list *map, if ((index = string_list_find_insert_index(map, old_email, 1)) < 0) { /* mailmap entry exists, invert index value */ index = -1 - index; + me = (struct mailmap_entry *)map->items[index].util; } else { /* create mailmap entry */ - struct string_list_item *item = string_list_insert_at_index(map, index, old_email); - item->util = xcalloc(1, sizeof(struct mailmap_entry)); - ((struct mailmap_entry *)item->util)->namemap.strdup_strings = 1; + struct string_list_item *item; + + item = string_list_insert_at_index(map, index, old_email); + me = xcalloc(1, sizeof(struct mailmap_entry)); + me->namemap.strdup_strings = 1; + me->namemap.cmp = namemap_cmp; + item->util = me; } - me = (struct mailmap_entry *)map->items[index].util; if (old_name == NULL) { - debug_mm("mailmap: adding (simple) entry for %s at index %d\n", old_email, index); + debug_mm("mailmap: adding (simple) entry for %s at index %d\n", + old_email, index); /* Replace current name and new email for simple entry */ if (new_name) { free(me->name); @@ -89,7 +107,8 @@ static void add_mapping(struct string_list *map, } } else { struct mailmap_info *mi = xcalloc(1, sizeof(struct mailmap_info)); - debug_mm("mailmap: adding (complex) entry for %s at index %d\n", old_email, index); + debug_mm("mailmap: adding (complex) entry for %s at index %d\n", + old_email, index); if (new_name) mi->name = xstrdup(new_name); if (new_email) @@ -98,11 +117,12 @@ static void add_mapping(struct string_list *map, } debug_mm("mailmap: '%s' <%s> -> '%s' <%s>\n", - old_name, old_email, new_name, new_email); + debug_str(old_name), old_email, + debug_str(new_name), debug_str(new_email)); } static char *parse_name_and_email(char *buffer, char **name, - char **email, int allow_empty_email) + char **email, int allow_empty_email) { char *left, *right, *nstart, *nend; *name = *email = NULL; @@ -122,7 +142,7 @@ static char *parse_name_and_email(char *buffer, char **name, while (nend > nstart && isspace(*nend)) --nend; - *name = (nstart < nend ? nstart : NULL); + *name = (nstart <= nend ? nstart : NULL); *email = left+1; *(nend+1) = '\0'; *right++ = '\0'; @@ -147,8 +167,7 @@ static void read_mailmap_line(struct string_list *map, char *buffer, if (!strncmp(buffer, abbrev, abblen)) { char *cp; - if (repo_abbrev) - free(*repo_abbrev); + free(*repo_abbrev); *repo_abbrev = xmalloc(len); for (cp = buffer + abblen; isspace(*cp); cp++) @@ -187,20 +206,17 @@ static int read_mailmap_file(struct string_list *map, const char *filename, return 0; } -static void read_mailmap_buf(struct string_list *map, - const char *buf, unsigned long len, - char **repo_abbrev) +static void read_mailmap_string(struct string_list *map, char *buf, + char **repo_abbrev) { - while (len) { - const char *end = strchrnul(buf, '\n'); - unsigned long linelen = end - buf + 1; - char *line = xmemdupz(buf, linelen); + while (*buf) { + char *end = strchrnul(buf, '\n'); - read_mailmap_line(map, line, repo_abbrev); + if (*end) + *end++ = '\0'; - free(line); - buf += linelen; - len -= linelen; + read_mailmap_line(map, buf, repo_abbrev); + buf = end; } } @@ -224,7 +240,7 @@ static int read_mailmap_blob(struct string_list *map, if (type != OBJ_BLOB) return error("mailmap is not a blob: %s", name); - read_mailmap_buf(map, buf, size, repo_abbrev); + read_mailmap_string(map, buf, repo_abbrev); free(buf); return 0; @@ -235,7 +251,7 @@ int read_mailmap(struct string_list *map, char **repo_abbrev) int err = 0; map->strdup_strings = 1; - map->cmp = strcasecmp; + map->cmp = namemap_cmp; if (!git_mailmap_blob && is_bare_repository()) git_mailmap_blob = "HEAD:.mailmap"; @@ -306,21 +322,25 @@ static struct string_list_item *lookup_prefix(struct string_list *map, } int map_user(struct string_list *map, - const char **email, size_t *emaillen, - const char **name, size_t *namelen) + const char **email, size_t *emaillen, + const char **name, size_t *namelen) { struct string_list_item *item; struct mailmap_entry *me; debug_mm("map_user: map '%.*s' <%.*s>\n", - *name, *namelen, *emaillen, *email); + (int)*namelen, debug_str(*name), + (int)*emaillen, debug_str(*email)); item = lookup_prefix(map, *email, *emaillen); if (item != NULL) { me = (struct mailmap_entry *)item->util; if (me->namemap.nr) { - /* The item has multiple items, so we'll look up on name too */ - /* If the name is not found, we choose the simple entry */ + /* + * The item has multiple items, so we'll look up on + * name too. If the name is not found, we choose the + * simple entry. + */ struct string_list_item *subitem; subitem = lookup_prefix(&me->namemap, *name, *namelen); if (subitem) @@ -341,8 +361,9 @@ int map_user(struct string_list *map, *name = mi->name; *namelen = strlen(*name); } - debug_mm("map_user: to '%.*s' <.*%s>\n", *namelen, *name, - *emaillen, *email); + debug_mm("map_user: to '%.*s' <%.*s>\n", + (int)*namelen, debug_str(*name), + (int)*emaillen, debug_str(*email)); return 1; } debug_mm("map_user: --\n"); |