@@ -14,7 +14,26 @@ static char const * const shortlog_usage[] = {
14
14
NULL
15
15
};
16
16
17
- static int compare_by_number (const void * a1 , const void * a2 )
17
+ /*
18
+ * The util field of our string_list_items will contain one of two things:
19
+ *
20
+ * - if --summary is not in use, it will point to a string list of the
21
+ * oneline subjects assigned to this author
22
+ *
23
+ * - if --summary is in use, we don't need that list; we only need to know
24
+ * its size. So we abuse the pointer slot to store our integer counter.
25
+ *
26
+ * This macro accesses the latter.
27
+ */
28
+ #define UTIL_TO_INT (x ) ((intptr_t)(x)->util)
29
+
30
+ static int compare_by_counter (const void * a1 , const void * a2 )
31
+ {
32
+ const struct string_list_item * i1 = a1 , * i2 = a2 ;
33
+ return UTIL_TO_INT (i2 ) - UTIL_TO_INT (i1 );
34
+ }
35
+
36
+ static int compare_by_list (const void * a1 , const void * a2 )
18
37
{
19
38
const struct string_list_item * i1 = a1 , * i2 = a2 ;
20
39
const struct string_list * l1 = i1 -> util , * l2 = i2 -> util ;
@@ -31,13 +50,9 @@ static void insert_one_record(struct shortlog *log,
31
50
const char * author ,
32
51
const char * oneline )
33
52
{
34
- const char * dot3 = log -> common_repo_prefix ;
35
- char * buffer , * p ;
36
53
struct string_list_item * item ;
37
54
const char * mailbuf , * namebuf ;
38
55
size_t namelen , maillen ;
39
- const char * eol ;
40
- struct strbuf subject = STRBUF_INIT ;
41
56
struct strbuf namemailbuf = STRBUF_INIT ;
42
57
struct ident_split ident ;
43
58
@@ -56,98 +71,95 @@ static void insert_one_record(struct shortlog *log,
56
71
strbuf_addf (& namemailbuf , " <%.*s>" , (int )maillen , mailbuf );
57
72
58
73
item = string_list_insert (& log -> list , namemailbuf .buf );
59
- if (item -> util == NULL )
60
- item -> util = xcalloc (1 , sizeof (struct string_list ));
61
-
62
- /* Skip any leading whitespace, including any blank lines. */
63
- while (* oneline && isspace (* oneline ))
64
- oneline ++ ;
65
- eol = strchr (oneline , '\n' );
66
- if (!eol )
67
- eol = oneline + strlen (oneline );
68
- if (starts_with (oneline , "[PATCH" )) {
69
- char * eob = strchr (oneline , ']' );
70
- if (eob && (!eol || eob < eol ))
71
- oneline = eob + 1 ;
72
- }
73
- while (* oneline && isspace (* oneline ) && * oneline != '\n' )
74
- oneline ++ ;
75
- format_subject (& subject , oneline , " " );
76
- buffer = strbuf_detach (& subject , NULL );
77
-
78
- if (dot3 ) {
79
- int dot3len = strlen (dot3 );
80
- if (dot3len > 5 ) {
81
- while ((p = strstr (buffer , dot3 )) != NULL ) {
82
- int taillen = strlen (p ) - dot3len ;
83
- memcpy (p , "/.../" , 5 );
84
- memmove (p + 5 , p + dot3len , taillen + 1 );
74
+
75
+ if (log -> summary )
76
+ item -> util = (void * )(UTIL_TO_INT (item ) + 1 );
77
+ else {
78
+ const char * dot3 = log -> common_repo_prefix ;
79
+ char * buffer , * p ;
80
+ struct strbuf subject = STRBUF_INIT ;
81
+ const char * eol ;
82
+
83
+ /* Skip any leading whitespace, including any blank lines. */
84
+ while (* oneline && isspace (* oneline ))
85
+ oneline ++ ;
86
+ eol = strchr (oneline , '\n' );
87
+ if (!eol )
88
+ eol = oneline + strlen (oneline );
89
+ if (starts_with (oneline , "[PATCH" )) {
90
+ char * eob = strchr (oneline , ']' );
91
+ if (eob && (!eol || eob < eol ))
92
+ oneline = eob + 1 ;
93
+ }
94
+ while (* oneline && isspace (* oneline ) && * oneline != '\n' )
95
+ oneline ++ ;
96
+ format_subject (& subject , oneline , " " );
97
+ buffer = strbuf_detach (& subject , NULL );
98
+
99
+ if (dot3 ) {
100
+ int dot3len = strlen (dot3 );
101
+ if (dot3len > 5 ) {
102
+ while ((p = strstr (buffer , dot3 )) != NULL ) {
103
+ int taillen = strlen (p ) - dot3len ;
104
+ memcpy (p , "/.../" , 5 );
105
+ memmove (p + 5 , p + dot3len , taillen + 1 );
106
+ }
85
107
}
86
108
}
87
- }
88
109
89
- string_list_append (item -> util , buffer );
110
+ if (item -> util == NULL )
111
+ item -> util = xcalloc (1 , sizeof (struct string_list ));
112
+ string_list_append (item -> util , buffer );
113
+ }
90
114
}
91
115
92
116
static void read_from_stdin (struct shortlog * log )
93
117
{
94
- char author [1024 ], oneline [1024 ];
118
+ struct strbuf author = STRBUF_INIT ;
119
+ struct strbuf oneline = STRBUF_INIT ;
95
120
96
- while (fgets (author , sizeof (author ), stdin ) != NULL ) {
97
- if (!(author [0 ] == 'A' || author [0 ] == 'a' ) ||
98
- !starts_with (author + 1 , "uthor: " ))
121
+ while (strbuf_getline_lf (& author , stdin ) != EOF ) {
122
+ const char * v ;
123
+ if (!skip_prefix (author .buf , "Author: " , & v ) &&
124
+ !skip_prefix (author .buf , "author " , & v ))
99
125
continue ;
100
- while (fgets ( oneline , sizeof ( oneline ), stdin ) &&
101
- oneline [ 0 ] != '\n' )
126
+ while (strbuf_getline_lf ( & oneline , stdin ) != EOF &&
127
+ oneline . len )
102
128
; /* discard headers */
103
- while (fgets ( oneline , sizeof ( oneline ), stdin ) &&
104
- oneline [ 0 ] == '\n' )
129
+ while (strbuf_getline_lf ( & oneline , stdin ) != EOF &&
130
+ ! oneline . len )
105
131
; /* discard blanks */
106
- insert_one_record (log , author + 8 , oneline );
132
+ insert_one_record (log , v , oneline . buf );
107
133
}
134
+ strbuf_release (& author );
135
+ strbuf_release (& oneline );
108
136
}
109
137
110
138
void shortlog_add_commit (struct shortlog * log , struct commit * commit )
111
139
{
112
- const char * author = NULL , * buffer ;
113
- struct strbuf buf = STRBUF_INIT ;
114
- struct strbuf ufbuf = STRBUF_INIT ;
115
-
116
- pp_commit_easy (CMIT_FMT_RAW , commit , & buf );
117
- buffer = buf .buf ;
118
- while (* buffer && * buffer != '\n' ) {
119
- const char * eol = strchr (buffer , '\n' );
120
-
121
- if (eol == NULL )
122
- eol = buffer + strlen (buffer );
140
+ struct strbuf author = STRBUF_INIT ;
141
+ struct strbuf oneline = STRBUF_INIT ;
142
+ struct pretty_print_context ctx = {0 };
143
+
144
+ ctx .fmt = CMIT_FMT_USERFORMAT ;
145
+ ctx .abbrev = log -> abbrev ;
146
+ ctx .subject = "" ;
147
+ ctx .after_subject = "" ;
148
+ ctx .date_mode .type = DATE_NORMAL ;
149
+ ctx .output_encoding = get_log_output_encoding ();
150
+
151
+ format_commit_message (commit , "%an <%ae>" , & author , & ctx );
152
+ if (!log -> summary ) {
153
+ if (log -> user_format )
154
+ pretty_print_commit (& ctx , commit , & oneline );
123
155
else
124
- eol ++ ;
125
-
126
- if (starts_with (buffer , "author " ))
127
- author = buffer + 7 ;
128
- buffer = eol ;
129
- }
130
- if (!author ) {
131
- warning (_ ("Missing author: %s" ),
132
- oid_to_hex (& commit -> object .oid ));
133
- return ;
156
+ format_commit_message (commit , "%s" , & oneline , & ctx );
134
157
}
135
- if (log -> user_format ) {
136
- struct pretty_print_context ctx = {0 };
137
- ctx .fmt = CMIT_FMT_USERFORMAT ;
138
- ctx .abbrev = log -> abbrev ;
139
- ctx .subject = "" ;
140
- ctx .after_subject = "" ;
141
- ctx .date_mode .type = DATE_NORMAL ;
142
- ctx .output_encoding = get_log_output_encoding ();
143
- pretty_print_commit (& ctx , commit , & ufbuf );
144
- buffer = ufbuf .buf ;
145
- } else if (* buffer ) {
146
- buffer ++ ;
147
- }
148
- insert_one_record (log , author , !* buffer ? "<none>" : buffer );
149
- strbuf_release (& ufbuf );
150
- strbuf_release (& buf );
158
+
159
+ insert_one_record (log , author .buf , oneline .len ? oneline .buf : "<none>" );
160
+
161
+ strbuf_release (& author );
162
+ strbuf_release (& oneline );
151
163
}
152
164
153
165
static void get_from_rev (struct rev_info * rev , struct shortlog * log )
@@ -294,14 +306,14 @@ void shortlog_output(struct shortlog *log)
294
306
295
307
if (log -> sort_by_number )
296
308
qsort (log -> list .items , log -> list .nr , sizeof (struct string_list_item ),
297
- compare_by_number );
309
+ log -> summary ? compare_by_counter : compare_by_list );
298
310
for (i = 0 ; i < log -> list .nr ; i ++ ) {
299
- struct string_list * onelines = log -> list .items [i ].util ;
300
-
311
+ const struct string_list_item * item = & log -> list .items [i ];
301
312
if (log -> summary ) {
302
- printf ("%6d\t%s\n" , onelines -> nr , log -> list . items [ i ]. string );
313
+ printf ("%6d\t%s\n" , ( int ) UTIL_TO_INT ( item ), item -> string );
303
314
} else {
304
- printf ("%s (%d):\n" , log -> list .items [i ].string , onelines -> nr );
315
+ struct string_list * onelines = item -> util ;
316
+ printf ("%s (%d):\n" , item -> string , onelines -> nr );
305
317
for (j = onelines -> nr - 1 ; j >= 0 ; j -- ) {
306
318
const char * msg = onelines -> items [j ].string ;
307
319
@@ -314,11 +326,11 @@ void shortlog_output(struct shortlog *log)
314
326
printf (" %s\n" , msg );
315
327
}
316
328
putchar ('\n' );
329
+ onelines -> strdup_strings = 1 ;
330
+ string_list_clear (onelines , 0 );
331
+ free (onelines );
317
332
}
318
333
319
- onelines -> strdup_strings = 1 ;
320
- string_list_clear (onelines , 0 );
321
- free (onelines );
322
334
log -> list .items [i ].util = NULL ;
323
335
}
324
336
0 commit comments