static void insert_one_record(struct shortlog *log, const char *author, const char *oneline) { struct string_list_item *item; item = string_list_insert(&log->list, author); if (log->summary) item->util = (void *)(UTIL_TO_INT(item) + 1); else { const char *dot3 = log->common_repo_prefix; char *buffer, *p; struct strbuf subject = STRBUF_INIT; const char *eol; /* Skip any leading whitespace, including any blank lines. */ while (*oneline && isspace(*oneline)) oneline++; eol = strchr(oneline, '\n'); if (!eol) eol = oneline + strlen(oneline); if (starts_with(oneline, "[PATCH")) { char *eob = strchr(oneline, ']'); if (eob && (!eol || eob < eol)) oneline = eob + 1; } while (*oneline && isspace(*oneline) && *oneline != '\n') oneline++; format_subject(&subject, oneline, " "); buffer = strbuf_detach(&subject, NULL); if (dot3) { int dot3len = strlen(dot3); if (dot3len > 5) { while ((p = strstr(buffer, dot3)) != NULL) { int taillen = strlen(p) - dot3len; memcpy(p, "/.../", 5); memmove(p + 5, p + dot3len, taillen + 1); } } } if (item->util == NULL) item->util = xcalloc(1, sizeof(struct string_list)); string_list_append(item->util, buffer); } }
void shortlog_output(struct shortlog *log) { int i, j; struct strbuf sb = STRBUF_INIT; if (log->sort_by_number) QSORT(log->list.items, log->list.nr, log->summary ? compare_by_counter : compare_by_list); for (i = 0; i < log->list.nr; i++) { const struct string_list_item *item = &log->list.items[i]; if (log->summary) { fprintf(log->file, "%6d\t%s\n", (int)UTIL_TO_INT(item), item->string); } else { struct string_list *onelines = item->util; fprintf(log->file, "%s (%d):\n", item->string, onelines->nr); for (j = onelines->nr - 1; j >= 0; j--) { const char *msg = onelines->items[j].string; if (log->wrap_lines) { strbuf_reset(&sb); add_wrapped_shortlog_msg(&sb, msg, log); fwrite(sb.buf, sb.len, 1, log->file); } else fprintf(log->file, " %s\n", msg); } putc('\n', log->file); onelines->strdup_strings = 1; string_list_clear(onelines, 0); free(onelines); } log->list.items[i].util = NULL; } strbuf_release(&sb); log->list.strdup_strings = 1; string_list_clear(&log->list, 1); clear_mailmap(&log->mailmap); }
static int compare_by_counter(const void *a1, const void *a2) { const struct string_list_item *i1 = a1, *i2 = a2; return UTIL_TO_INT(i2) - UTIL_TO_INT(i1); }
static void insert_one_record(struct shortlog *log, const char *author, const char *oneline) { struct string_list_item *item; const char *mailbuf, *namebuf; size_t namelen, maillen; struct strbuf namemailbuf = STRBUF_INIT; struct ident_split ident; if (split_ident_line(&ident, author, strlen(author))) return; namebuf = ident.name_begin; mailbuf = ident.mail_begin; namelen = ident.name_end - ident.name_begin; maillen = ident.mail_end - ident.mail_begin; map_user(&log->mailmap, &mailbuf, &maillen, &namebuf, &namelen); strbuf_add(&namemailbuf, namebuf, namelen); if (log->email) strbuf_addf(&namemailbuf, " <%.*s>", (int)maillen, mailbuf); item = string_list_insert(&log->list, namemailbuf.buf); if (log->summary) item->util = (void *)(UTIL_TO_INT(item) + 1); else { const char *dot3 = log->common_repo_prefix; char *buffer, *p; struct strbuf subject = STRBUF_INIT; const char *eol; /* Skip any leading whitespace, including any blank lines. */ while (*oneline && isspace(*oneline)) oneline++; eol = strchr(oneline, '\n'); if (!eol) eol = oneline + strlen(oneline); if (starts_with(oneline, "[PATCH")) { char *eob = strchr(oneline, ']'); if (eob && (!eol || eob < eol)) oneline = eob + 1; } while (*oneline && isspace(*oneline) && *oneline != '\n') oneline++; format_subject(&subject, oneline, " "); buffer = strbuf_detach(&subject, NULL); if (dot3) { int dot3len = strlen(dot3); if (dot3len > 5) { while ((p = strstr(buffer, dot3)) != NULL) { int taillen = strlen(p) - dot3len; memcpy(p, "/.../", 5); memmove(p + 5, p + dot3len, taillen + 1); } } } if (item->util == NULL) item->util = xcalloc(1, sizeof(struct string_list)); string_list_append(item->util, buffer); } }