NULL
};
-static int compare_by_number(const void *a1, const void *a2)
+/*
+ * The util field of our string_list_items will contain one of two things:
+ *
+ * - if --summary is not in use, it will point to a string list of the
+ * oneline subjects assigned to this author
+ *
+ * - if --summary is in use, we don't need that list; we only need to know
+ * its size. So we abuse the pointer slot to store our integer counter.
+ *
+ * This macro accesses the latter.
+ */
+#define UTIL_TO_INT(x) ((intptr_t)(x)->util)
+
+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 int compare_by_list(const void *a1, const void *a2)
{
const struct string_list_item *i1 = a1, *i2 = a2;
const struct string_list *l1 = i1->util, *l2 = i2->util;
strbuf_addf(&namemailbuf, " <%.*s>", (int)maillen, mailbuf);
item = string_list_insert(&log->list, namemailbuf.buf);
- if (item->util == NULL)
- item->util = xcalloc(1, sizeof(struct string_list));
if (log->summary)
- string_list_append(item->util, xstrdup(""));
+ item->util = (void *)(UTIL_TO_INT(item) + 1);
else {
const char *dot3 = log->common_repo_prefix;
char *buffer, *p;
}
}
+ if (item->util == NULL)
+ item->util = xcalloc(1, sizeof(struct string_list));
string_list_append(item->util, buffer);
}
}
struct strbuf author = STRBUF_INIT;
struct strbuf oneline = STRBUF_INIT;
- while (strbuf_getline(&author, stdin, '\n') != EOF) {
+ while (strbuf_getline_lf(&author, stdin) != EOF) {
const char *v;
if (!skip_prefix(author.buf, "Author: ", &v) &&
!skip_prefix(author.buf, "author ", &v))
continue;
- while (strbuf_getline(&oneline, stdin, '\n') != EOF &&
+ while (strbuf_getline_lf(&oneline, stdin) != EOF &&
oneline.len)
; /* discard headers */
- while (strbuf_getline(&oneline, stdin, '\n') != EOF &&
+ while (strbuf_getline_lf(&oneline, stdin) != EOF &&
!oneline.len)
; /* discard blanks */
insert_one_record(log, v, oneline.buf);
ctx.output_encoding = get_log_output_encoding();
format_commit_message(commit, "%an <%ae>", &author, &ctx);
- /* we can detect a total failure only by seeing " <>" in the output */
- if (author.len <= 3) {
- warning(_("Missing author: %s"),
- oid_to_hex(&commit->object.oid));
- goto out;
- }
-
if (!log->summary) {
if (log->user_format)
pretty_print_commit(&ctx, commit, &oneline);
insert_one_record(log, author.buf, oneline.len ? oneline.buf : "<none>");
-out:
strbuf_release(&author);
strbuf_release(&oneline);
}
if (log->sort_by_number)
qsort(log->list.items, log->list.nr, sizeof(struct string_list_item),
- compare_by_number);
+ log->summary ? compare_by_counter : compare_by_list);
for (i = 0; i < log->list.nr; i++) {
- struct string_list *onelines = log->list.items[i].util;
-
+ const struct string_list_item *item = &log->list.items[i];
if (log->summary) {
- printf("%6d\t%s\n", onelines->nr, log->list.items[i].string);
+ printf("%6d\t%s\n", (int)UTIL_TO_INT(item), item->string);
} else {
- printf("%s (%d):\n", log->list.items[i].string, onelines->nr);
+ struct string_list *onelines = item->util;
+ printf("%s (%d):\n", item->string, onelines->nr);
for (j = onelines->nr - 1; j >= 0; j--) {
const char *msg = onelines->items[j].string;
printf(" %s\n", msg);
}
putchar('\n');
+ onelines->strdup_strings = 1;
+ string_list_clear(onelines, 0);
+ free(onelines);
}
- onelines->strdup_strings = 1;
- string_list_clear(onelines, 0);
- free(onelines);
log->list.items[i].util = NULL;
}